bash array подскажите

На самом деле это единственный раздел про unix на этом форуме

Модераторы: /dev/random, Модераторы разделов

LittleJohn
Сообщения: 5

bash array подскажите

Сообщение LittleJohn »

Так привык не пользоваться массивами в bash, что теперь не могу и придумать где их использовать:)
Может кто то подскажет в каких случаях массивы облегчают жизнь.
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: bash array подскажите

Сообщение watashiwa_daredeska »

LittleJohn писал(а):
17.01.2011 19:50
Может кто то подскажет в каких случаях массивы облегчают жизнь.
При универсальной обработке произвольных аргументов. Для примера, попробуйте написать скрипт следующего вида:

Код: Выделить всё

Usage: script [options] [--] command [args]

Options:
  -s    Run command under sudo
  -t    Run command under strace
  -u USER   Run with this user's rights. Implies sudo.

Examples:
  script echo 123
  Just executes `echo 123`.

  script -s echo 123
  Executes `sudo echo 123`.

  script -u somebody -t echo 123
  Executes `sudo -u somebody strace echo 123`.
Соответственно, штуковина должна работать с любыми аргументами, включая содержащие символы с кодами 1..32, кавычками и прочими спец. символами shell.
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: bash array подскажите

Сообщение t.t »

watashiwa_daredeska писал(а):
17.01.2011 20:14
LittleJohn писал(а):
17.01.2011 19:50
Может кто то подскажет в каких случаях массивы облегчают жизнь.
При универсальной обработке произвольных аргументов. Для примера, попробуйте написать скрипт следующего вида:

Код: Выделить всё

Usage: script [options] [--] command [args]

Options:
  -s    Run command under sudo
  -t    Run command under strace
  -u USER   Run with this user's rights. Implies sudo.

Examples:
  script echo 123
  Just executes `echo 123`.

  script -s echo 123
  Executes `sudo echo 123`.

  script -u somebody -t echo 123
  Executes `sudo -u somebody strace echo 123`.
Соответственно, штуковина должна работать с любыми аргументами, включая содержащие символы с кодами 1..32, кавычками и прочими спец. символами shell.
В целом пример хороший, но именно для _работы_ с массивами можно добавить вариант, где нужно, скажем, перетасовать аргументы местами. А не просто один раз вставить "$@". (:
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: bash array подскажите

Сообщение sash-kan »

watashiwa_darede... писал(а):
17.01.2011 20:14
Для примера, попробуйте написать скрипт следующего вида
такой подойдёт?

Код: Выделить всё

#!/bin/bash
unset sudo_c user_c
while getopts 'su:' flag
do
  case "$flag" in
    "s") sudo_c="sudo";;
    "u") if [ ! "$user_c" ]
      then sudo_c="sudo"; user_c="-u $OPTARG"
      fi;;
  esac
done
shift $((OPTIND-1))
echo $sudo_c $user_c "$@"
в последней строке стоит echo (а не eval) для тестов:
$ ./script -s -u root -s a$(echo -e '\0001')b
sudo -u root ab
$ ./script -s -u root -s a$(echo -e '\0001')b | hd
00000000 73 75 64 6f 20 2d 75 20 72 6f 6f 74 20 61 01 62 |sudo -u root a.b|
00000010 0a |.|
00000011

после замены echo на eval:
$ ./script -s -u root -s a$(echo -e '\0001')b
sudo: ab: command not found

watashiwa_darede... писал(а):
17.01.2011 20:14
и прочими спец. символами shell.
гхм. при вводе команды текущий шелл влезет грязными лапками и сделает подстановки. есть вариант, как это можно обойти программно?

p.s. самое главное-то: а зачем массивы в таком скрипте?
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: bash array подскажите

Сообщение ZyX »

sash-kan писал(а):
17.01.2011 23:18
watashiwa_darede... писал(а):
17.01.2011 20:14
Для примера, попробуйте написать скрипт следующего вида
такой подойдёт?

Код: Выделить всё

#!/bin/bash
unset sudo_c user_c
while getopts 'su:' flag
do
  case "$flag" in
    "s") sudo_c="sudo";;
    "u") if [ ! "$user_c" ]
      then sudo_c="sudo"; user_c="-u $OPTARG"
      fi;;
  esac
done
shift $((OPTIND-1))
echo $sudo_c $user_c "$@"
в последней строке стоит echo (а не eval) для тестов:
$ ./script -s -u root -s a$(echo -e '\0001')b
sudo -u root ab
$ ./script -s -u root -s a$(echo -e '\0001')b | hd
00000000 73 75 64 6f 20 2d 75 20 72 6f 6f 74 20 61 01 62 |sudo -u root a.b|
00000010 0a |.|
00000011

после замены echo на eval:
$ ./script -s -u root -s a$(echo -e '\0001')b
sudo: ab: command not found

watashiwa_darede... писал(а):
17.01.2011 20:14
и прочими спец. символами shell.
гхм. при вводе команды текущий шелл влезет грязными лапками и сделает подстановки. есть вариант, как это можно обойти программно?

И чем это мешает? vim +'set ft=vim' a\ b\"c, screen -m vim +'set ft=vim' a\ b\"c и exec vim +'set ft=vim' a\ b\"c работают одиноково хорошо.

// В zsh можно для этого переопределить widget accept-line.

sash-kan писал(а):
17.01.2011 23:18
p.s. самое главное-то: а зачем массивы в таком скрипте?

Если массивы там не нужны, уберите $@.

Кстати, напишите на bash скрипт, который принимает такие же аргумента, как и zip, но создаёт .tar.gz архив. Так как это очень долго, то можно оставить только аргументы -d, -g, -x, -i, -O, -nw, -q, -v, -y, -r при том, что везде, где могут быть спецсимволы, они должны корректно обрабатываться. Также можно забыть о длинных формах и -{key}{value}, оставив только -{key} {value}. Без создания новых массивов. Считать, что tar использует те же регулярные выражения, что и zip. Потом сравним версию без массивов и с ними.
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: bash array подскажите

Сообщение watashiwa_daredeska »

sash-kan писал(а):
17.01.2011 23:18
в последней строке стоит echo (а не eval) для тестов:
А eval там вообще нельзя, ибо он непоправимо покорёжит "$@". Надо просто $sudo_c $user_c "$@".

t.t писал(а):
17.01.2011 23:00
В целом пример хороший
В целом пример плохой, как показало решение sash-kan. Тут спасает то, что sudo, username и strace не содержат «нехороших» символов по определению. Если задача в склеивании большой команды из нескольких кусочков, которые задаются пользователем и могут содержать гадости, то всё становится хуже. Просто a la $sudo_c без кавычек уже не напишешь, а "$sudo_c" съедает деление на отдельные токены, а eval "$sudo_c" творит страшное без дополнительного правильного закавычивания того, что внутри. Иногда можно, конечно играть во что-нибудь вроде set -- cmd "arg 1" "arg 2" "$@", но не всегда.

sash-kan писал(а):
17.01.2011 23:18
гхм. при вводе команды текущий шелл влезет грязными лапками и сделает подстановки. есть вариант, как это можно обойти программно?
При вводе можно закавычить. Я имел в виду, что если я ввел башевское $'xyz\n$(cat /etc/passwd)\n\e[31m', то оно должно таким и остаться, вместе со всеми переводами строк, знаками доллара и пр., а не развернуться где-то в потрохах скрипта.

Ещё один use case вспомнился, где мне array'и помогли. Есть набор строк. «Нехороших» с т.з. шелла (пробелы, кавычки и т.п.). Нужно по ним прогнать for.
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: bash array подскажите

Сообщение watashiwa_daredeska »

sash-kan писал(а):
17.01.2011 23:18
после замены echo на eval:
$ ./script -s -u root -s a$(echo -e '\0001')b
sudo: ab: command not found
Хуже того, $ ./script -s -u root -s 'a$(echo -e '\0001')b' выдаст то же самое, что уже не правильно. Именно потому, что eval.
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: bash array подскажите

Сообщение t.t »

watashiwa_daredeska писал(а):
17.01.2011 23:59
а "$sudo_c" съедает деление на отдельные токены
Вот тут не совсем понял. Какое деление съедают кавычки? Пробелами? То, что попадёт в массив, к этому времени уже будет разделено.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: bash array подскажите

Сообщение watashiwa_daredeska »

t.t писал(а):
18.01.2011 00:47
Какое деление съедают кавычки? Пробелами?
Да.

t.t писал(а):
18.01.2011 00:47
То, что попадёт в массив
Если без массивов решать задачу. Массив-то как раз эту проблему позволяет решить легко.
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: bash array подскажите

Сообщение t.t »

watashiwa_daredeska писал(а):
18.01.2011 01:14
t.t писал(а):
18.01.2011 00:47
Какое деление съедают кавычки? Пробелами?
Да.

t.t писал(а):
18.01.2011 00:47
То, что попадёт в массив
Если без массивов решать задачу. Массив-то как раз эту проблему позволяет решить легко.
А, тогда понял. (: Да, без массивов та ещё работа получится. Не зря ведь, в частности, упомянутый $@ встречается в скриптах гораздо чаще, чем $*.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: bash array подскажите

Сообщение sash-kan »

ZyX писал(а):
17.01.2011 23:56
Если массивы там не нужны, уберите $@.
отличное предложение. «доберитесь до информации, хранящейся _только_ в массиве, не используя массива»
ну что ж, попробую «спеть о том же самом в несколько более сложных словах».
требуется, чтобы команда
$ ./script vim +'set ft=vim' a\ b\"c
запускала vim для редактирования файл «a b"c», установив filetype в значением "vim" и при этом не использовался (наверно, единственный встроенный) массив $@? извольте:

Код: Выделить всё

#!/bin/bash
c="$1"
shift
while [ "$1" ]; do
  c="$c '$1'"
  shift
done
eval $c
у меня — работает. т.е. формирует команду из отдельных токенов.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: bash array подскажите

Сообщение watashiwa_daredeska »

sash-kan писал(а):
18.01.2011 04:21
у меня — работает
Не верю! c="$c '$1'" совершенно недостаточно, чтобы одинарная кавычка из $1 корректно обрабатывалась потом в eval.
Нужно чуть сложнее: c="$c '$(echo "$1" | sed "s/'/'\\\''/g")'" Однако, никто не говорит, что массивы позволяют что-то, чего нельзя без них. Ты же понимаешь: тьюринг-полный и т.д. и т.п. Но некоторые вещи с массивами делать проще и читать потом легче, чем вот ту фигатень с sed'ом.
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: bash array подскажите

Сообщение t.t »

watashiwa_daredeska писал(а):
18.01.2011 01:14
t.t писал(а):
18.01.2011 00:47
Какое деление съедают кавычки? Пробелами?
Да.

t.t писал(а):
18.01.2011 00:47
То, что попадёт в массив
Если без массивов решать задачу. Массив-то как раз эту проблему позволяет решить легко.
Собственно, я к тому и говорил: пример твой вовсе не плохой, т.к. преимущество использования массивов демонстрирует. По коду sash-kan см. замечание ZyX: массив у него всё-таки есть.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: bash array подскажите

Сообщение t.t »

sash-kan писал(а):
18.01.2011 04:21
ZyX писал(а):
17.01.2011 23:56
Если массивы там не нужны, уберите $@.
отличное предложение. «доберитесь до информации, хранящейся _только_ в массиве, не используя массива»
С чего вдруг «только»? Она и в строке хранится: $*.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5404
ОС: Gentoo

Re: bash array подскажите

Сообщение /dev/random »

ZyX писал(а):
17.01.2011 23:56
Если массивы там не нужны, уберите $@.

$@ - не массив, а просто подстановка в строку всех аргументов скрипта/функции, с корректным делением на аргументы.
И, кстати, в POSIX массивов нет, а $@ - есть.
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: bash array подскажите

Сообщение t.t »

Кстати, в ABS-е обычно неплохие примеры. Может и по массивам подойдут?
http://tldp.org/LDP/abs/html/arrays.html
http://rus-linux.net/MyLDP/BOOKS/abs-guide...ook.html#ARRAYS
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: bash array подскажите

Сообщение sash-kan »

/dev/random писал(а):
18.01.2011 10:53
ZyX писал(а):
17.01.2011 23:56
Если массивы там не нужны, уберите $@.

$@ - не массив, а просто подстановка в строку всех аргументов скрипта/функции, с корректным делением на аргументы.
И, кстати, в POSIX массивов нет, а $@ - есть.
спасибо. а то сбивают с толку, понимаешь…

LittleJohn писал(а):
17.01.2011 19:50
Может кто то подскажет в каких случаях массивы облегчают жизнь.
в том случае когда у вас любимый стиль такой.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: bash array подскажите

Сообщение sash-kan »

watashiwa_daredeska писал(а):
18.01.2011 04:37
sash-kan писал(а):
18.01.2011 04:21
у меня — работает
Не верю! c="$c '$1'" совершенно недостаточно, чтобы одинарная кавычка из $1 корректно обрабатывалась потом в eval.
Нужно чуть сложнее: c="$c '$(echo "$1" | sed "s/'/'\\\''/g")'" Однако, никто не говорит, что массивы позволяют что-то, чего нельзя без них. Ты же понимаешь: тьюринг-полный и т.д. и т.п. Но некоторые вещи с массивами делать проще и читать потом легче, чем вот ту фигатень с sed'ом.
кстати, очень хотелось бы увидеть пример более простой и легче читаемой работы с переменной $@..
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: bash array подскажите

Сообщение watashiwa_daredeska »

sash-kan писал(а):
18.01.2011 19:17
очень хотелось бы увидеть пример более простой и легче читаемой работы с переменной $@..
Это ты о чем?
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: bash array подскажите

Сообщение sash-kan »

watashiwa_darede... писал(а):
18.01.2011 19:31
Это ты о чем?
ну, я вот это попробовал написать без массивов:
watashiwa_darede... писал(а):
17.01.2011 20:14
Для примера, попробуйте написать скрипт следующего вида

был раскритикован за некорректность. сделал по-другому. опять раскритикован. с добавкой про сложность и нечитабельность.
я совершенно не против критики и безоговорочно признаю её.
только прошу — покажи, пожалуйста, как реализовать твой же пример проще и нагляднее.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: bash array подскажите

Сообщение watashiwa_daredeska »

sash-kan писал(а):
18.01.2011 19:42
покажи, пожалуйста, как реализовать твой же пример проще и нагляднее.
Слегка модифицированный пример с двумя возможными префиксными командами и аргументами к ним в свободной форме:

Код: Выделить всё

#!/bin/bash
# wrapper.sh без массивов

quote() {
  echo -n "'"
  echo -n "$1" | sed "s/'/'\\\''/g"
  echo -n "'"
}

unset prefix_a prefix_b command

eval "set -- $(getopt -o +a:b: -- "$@")"
while :; do
  case "$1" in
    -a)
      prefix_a="prefix_a $(quote "$2")"
      shift
    ;;
    -b)
      prefix_b="prefix_b $(quote "$2")"
      shift
    ;;
    --)
      shift
      break
    ;;
  esac
  shift
done
command="$prefix_a $prefix_b"
for arg; do
  command="$command $(quote "$arg")"
done
eval "args $command"

Код: Выделить всё

#!/bin/bash
# wrapper.sh с массивами

unset prefix_a prefix_b

eval "set -- $(getopt -o +a:b: -- "$@")"
while :; do
  case "$1" in
    -a)
      prefix_a=(prefix_a "$2")
      shift
    ;;
    -b)
      prefix_b=(prefix_b "$2")
      shift
    ;;
    --)
      shift
      break
    ;;
  esac
  shift
done
args "${prefix_a[@]}" "${prefix_b[@]}" "$@"
Программа args — это мой скриптик, специально для отладки передаваемых параметров в программы:

Код: Выделить всё

#!/bin/sh
# args

i=0
while [ $# -gt 0 ]; do
    echo "[$i]: '$1'"
    shift
    i=$((i+1))
done

Примеры:

user@localhost

~$ ./wrapper.sh cmd [0]: 'cmd' ~$ ./wrapper.sh $'multiline\ncmd' [0]: 'multiline cmd' ~$ ./wrapper.sh -a A cmd [0]: 'prefix_a' [1]: 'A' [2]: 'cmd' ~$ ./wrapper.sh -a A\'B\ C$'\n'D cmd [0]: 'prefix_a' [1]: 'A'B C D' [2]: 'cmd' ~$ ./wrapper.sh -a A\'B\ C$'\n'D -b E\'F\ G$'\n'H cmd [0]: 'prefix_a' [1]: 'A'B C D' [2]: 'prefix_b' [3]: 'E'F G H' [4]: 'cmd'

Очевидно, что если убрать args, то будут выполняться выводимые команды в точности.
Вот как-то так.
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: bash array подскажите

Сообщение sash-kan »

watashiwa_darede...
или я чего-то не понимаю, или не вижу, в каком месте тут наличествует «простота и легкочитабельность». да и вообще кардинальных отличий от написанного мною что-то тоже не улавливаю.
ткни меня, пожалуйста, носом в то место, где «некоторые вещи с массивами делать проще и читать потом легче, чем вот ту фигатень с sed'ом».
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: bash array подскажите

Сообщение watashiwa_daredeska »

Прелесть в том, что без массивов нужно квотировать явно вручную один и только один раз, ни на секунду не забывая, что ты уже отквотировал ранее, а что еще нет, иначе получится полная фигня. И в результате, без использования массивов появляются всякие прелести, вроде того цикла по всем аргументам в конце. И это еще очень простой как топор случай, где всё очень легко. Если появится хоть какая более-менее сложная логика обработки и преобразования аргументов, начнется полный ахтунг с этим квотированием. А вот с массивами всё просто.

sash-kan писал(а):
19.01.2011 11:36
не вижу, в каком месте тут наличествует «простота и легкочитабельность»
Если отбросить парсинг опций, то в скрипте с использованием массивов остается ровно одна строчка: та, которая последняя, а в скрипте без массивов еще функция и цикл, который надо не забыть, иначе всё пропало.

sash-kan писал(а):
19.01.2011 11:36
кардинальных отличий от написанного мною что-то тоже не улавливаю.
Твои примеры, если без изменений, не будет работать с аргументами из моих примеров.
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: bash array подскажите

Сообщение sash-kan »

watashiwa_darede... писал(а):
19.01.2011 13:44
Если отбросить парсинг опций, то в скрипте с использованием массивов остается ровно одна строчка: та, которая последняя, а в скрипте без массивов еще функция и цикл, который надо не забыть, иначе всё пропало.
то же самое останется. ведь $@ — это не массив.

при разборе аргументов — да, понадобится эскейпить кавычки при разделении на токены. других преимуществ не наблюдаю.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: bash array подскажите

Сообщение t.t »

sash-kan писал(а):
19.01.2011 21:36
watashiwa_darede... писал(а):
19.01.2011 13:44
Если отбросить парсинг опций, то в скрипте с использованием массивов остается ровно одна строчка: та, которая последняя, а в скрипте без массивов еще функция и цикл, который надо не забыть, иначе всё пропало.
то же самое останется. ведь $@ — это не массив.
Он про свои два скрипта, а не про твой. Или я тебя неправильно понял?
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: bash array подскажите

Сообщение sash-kan »

t.t писал(а):
19.01.2011 22:20
sash-kan писал(а):
19.01.2011 21:36
watashiwa_darede... писал(а):
19.01.2011 13:44
Если отбросить парсинг опций, то в скрипте с использованием массивов остается ровно одна строчка: та, которая последняя, а в скрипте без массивов еще функция и цикл, который надо не забыть, иначе всё пропало.
то же самое останется. ведь $@ — это не массив.
Он про свои два скрипта, а не про твой. Или я тебя неправильно понял?
в своём первом скрипте wd зачем-то усложнил конструкцию, организовав цикл по списку аргументов. естественно, это не нужно. можно напрямую взять значение специальной переменной $@. ведь это не array, а специальная переменная (rtmb → read the man bash).
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: bash array подскажите

Сообщение drBatty »

LittleJohn писал(а):
17.01.2011 19:50
Может кто то подскажет в каких случаях массивы облегчают жизнь.

вот как использует массивы Патрег:

Код: Выделить всё

# Config information for eth0:
IPADDR[0]=""
NETMASK[0]=""
USE_DHCP[0]="yes"
DHCP_HOSTNAME[0]=""
DHCP_KEEPRESOLV[0]="yes"

# Config information for eth1:
IPADDR[1]="172.16.1.1"
NETMASK[1]="255.255.255.0"
USE_DHCP[1]="no"
DHCP_HOSTNAME[1]=""

DEBUG_ETH_UP[1]="yes"


тут каждый сетевой интерфейс описывается одним эл-том массива, а потом они поднимаются единой функцией, в цикле.

Код: Выделить всё

# Function to start the network:
start() {
  lo_up
  for i in ${IFNAME[@]}; do
    if_up $i
  done
  gateway_up
  if [ -x /etc/rc.d/rc.dhcpd ]; then
    /etc/rc.d/rc.dhcpd start
  fi
}


это позволяет удобно задавать параметры для каждого интерфейса. Альтернативный вариант с sed был-бы более неуклюж в данном случае.

ЗЫЖ а про кавычки вы зря - используйте sed-скрипты, в которых можно юзать любые кавычки.


http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: bash array подскажите

Сообщение watashiwa_daredeska »

sash-kan писал(а):
20.01.2011 11:31
можно напрямую взять значение специальной переменной $@.
Нельзя. Потому что для eval нужен дополнительный уровень квотирования, а без eval аргументы в общем виде тоже не обработать.
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5404
ОС: Gentoo

Re: bash array подскажите

Сообщение /dev/random »

watashiwa_daredeska писал(а):
20.01.2011 14:47
а без eval аргументы в общем виде тоже не обработать.

Почему это?

[ -n "$foo" ] && set -- foo "$foo" "$@"
[ -n "$bar" ] && set -- bar "$bar" "$@"
script "$@"
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: bash array подскажите

Сообщение watashiwa_daredeska »

/dev/random писал(а):
20.01.2011 14:54
Почему это?

[ -n "$foo" ] && set -- foo "$foo" "$@"
[ -n "$bar" ] && set -- bar "$bar" "$@"
script "$@"
watashiwa_darede... писал(а):
17.01.2011 23:59
Иногда можно, конечно играть во что-нибудь вроде set -- cmd "arg 1" "arg 2" "$@", но не всегда.
Спасибо сказали: