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

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

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

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

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

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

watashiwa_daredeska писал(а):
20.01.2011 14:47
sash-kan писал(а):
20.01.2011 11:31
можно напрямую взять значение специальной переменной $@.
Нельзя. Потому что для eval нужен дополнительный уровень квотирования, а без eval аргументы в общем виде тоже не обработать.

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


у тебя же во втором твоём скрипте без eval-а обходится:
watashiwa_darede... писал(а):
18.01.2011 21:11
args "${prefix_a[@]}" "${prefix_b[@]}" "$@"
если убрать выделенное (относящееся к обработке опций), останется
args "$@"
где тут eval?
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

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

Сообщение watashiwa_daredeska »

sash-kan писал(а):
20.01.2011 19:03
у тебя же во втором твоём скрипте без eval-а обходится:
Потому что во втором скрипте prefix_a и prefix_b — массивы. Поэтому обходится без eval. В первом скрипте, без массивов, без eval не обходится, потому нужно дополнительно квотировать "$@" для eval.

Вообще, чего спорить, я не понимаю. Вот в твоем первом скрипте представь, что значение username не ограничено именно username'ом, а может быть произвольным, т.е. содержать любые символы, кроме \0, и быть пустым. И сделай так, чтобы финальная команда формировалась корректно с сохранением этого параметра, а не корежила его, как сейчас.
Примеры тестовых значений есть выше: A\'B\ C$'\n'D и ''.

sash-kan писал(а):
20.01.2011 19:03
если убрать выделенное (относящееся к обработке опций), останется
Я не это имел в виду, а getopt(s) и сам цикл обработки опций. prefix_a и prefix_b остаются, хотя и содержат разное: в одном случае заквотированные значения, во втором — массивы.
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

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

Сообщение watashiwa_daredeska »

sash-kan
Вот моя версия твоего скрипта про sudo, которая корректно обрабатывает параметр опции -u:

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

#!/bin/bash
quote() {
  echo -n "'"
  echo -n "$1" | sed "s/'/'\\\''/g"
  echo -n "'"
}
unset sudo_c user_c
while getopts 'su:' flag
do
  case "$flag" in
    "s") sudo_c=sudo;;
    "u") sudo_c=sudo
      user_c="-u $(quote "$OPTARG")"
;;
  esac
done
shift $((OPTIND-1))
command="$sudo_c $user_c"
for arg; do
  command="$command $(quote "$arg")"
done
eval "args $command"
Если у тебя получится без quote и eval реализовать корректную обработку A\'B\ C$'\n'D и '', я с удовольствием погляжу, ибо не знаю такого способа, кроме массивов (UPD: и кроме set -- ...).
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5404
ОС: Gentoo

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

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

watashiwa_daredeska писал(а):
20.01.2011 20:36
(UPD: и кроме set -- ...).

В который раз уже вижу в этой теме это "кроме" для "set --". Чем он так не угодил?
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

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

Сообщение watashiwa_daredeska »

/dev/random писал(а):
20.01.2011 20:39
Чем он так не угодил?
Если задача стоит в конструировании не одной команды, а, например, пайпа из нескольких, то set -- ... — это ещё больший головняк, чем quote. Но в достаточно простых случаях, конечно, имеет право на жизнь.
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

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

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

watashiwa_daredeska писал(а):
20.01.2011 20:47
/dev/random писал(а):
20.01.2011 20:39
Чем он так не угодил?
Если задача стоит в конструировании не одной команды, а, например, пайпа из нескольких, то set -- ... — это ещё больший головняк, чем quote. Но в достаточно простых случаях, конечно, имеет право на жизнь.
Справедливости ради:

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

$ { set q w e; echo "$@"; } | { set w; sed s/"$@"/r/; }
q r e
Ну и где здесь больший головняк, чем с массивами, — и тем более, чем с квотированием?
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

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

Сообщение watashiwa_daredeska »

t.t писал(а):
21.01.2011 10:33
Ну и где здесь больший головняк, чем с массивами, — и тем более, чем с квотированием?
Не всегда можно обойтись одним set в каждом блоке: см. #29. Это захламляет и читать такой пайп может быть довольно тяжело, гораздо тяжелее, чем самый обычный пайп с подстановками массивов. С квотированием, пожалуй, да, погеморройнее получится, чем с set.
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

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

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

watashiwa_daredeska писал(а):
21.01.2011 11:16
t.t писал(а):
21.01.2011 10:33
Ну и где здесь больший головняк, чем с массивами, — и тем более, чем с квотированием?
Не всегда можно обойтись одним set в каждом блоке: см. #29. Это захламляет и читать такой пайп может быть довольно тяжело, гораздо тяжелее, чем самый обычный пайп с подстановками массивов. С квотированием, пожалуй, да, погеморройнее получится, чем с set.
Захламляет — возможно; читать тяжелее — субъективно; _гораздо_ тяжелее — готов поспорить. На мой взгляд, вот такое

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

{
  set -- "$param1" "$param2"
  command1 "$@"
} | {
  set -- "$param3" "$param4"
  command2 "$@"
  set -- "$param5" "$param6" "$param7"
  command3 "$@"
} | {
  set -- "$param8" "$param9"
  command4 "$@"
}
читается даже легче, чем

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

command1 params1[@] | { command2 params2[@]; command3 params3[@]; } | command4 params4[@]
т.к. массивы определены где-то в стороне, а в первом случае все параметры «прямо в коде».
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

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

Сообщение watashiwa_daredeska »

t.t писал(а):
21.01.2011 13:00
читается даже легче, чем
Соглашусь, что это субъективно. Как по мне, так при говорящих именах массивов второе читается легче, даже при использовании дополнительных кавычек, как положено.
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

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

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

watashiwa_daredeska писал(а):
20.01.2011 20:36
Если у тебя получится без quote и eval реализовать корректную обработку A\'B\ C$'\n'D и '', я с удовольствием погляжу, ибо не знаю такого способа, кроме массивов (UPD: и кроме set -- ...).
с условием, что в параметре не будет упомянут какой-нибудь конкретный символ (\x01, например), разбить на токены (и, соответственно, не использовать eval) — несложно.
но пока не придумал, как объехать такое условие.

p.s. естественно, quote не требуется.

upd. условие, конечно, можно переформулировать произвольно. например, «внутри параметра не может быть такой-то подстроки (к примеру, "----")».
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали: