Re: Подстановка переменн ого числа аргументов

2010-10-28 Thread Oleksandr Gavenko

On 28.10.2010 15:14, Serhiy Storchaka wrote:

Здравствуйте.

Прошу прощения за такой элементарный и не совсем тематический вопрос, но это
наиболее компетентная группа, которую я сейчас читаю.

Задача. В зависимости от некоторых условий необходимо вызвать команду с
дополнительными аргументами или без них. Например:

if somecheck
then
   OPTS="--foo $FOO"
else
   OPTS=""
fi
bar -ziq $OPTS bla-bla-bla

Проблема в том, что $FOO может быть пустым (тогда подставится лишь один
аргумент --foo) или содержать пробелы (тогда подставится больше двух
аргументов).

Можно, конечно, написать:

if somecheck
then
   bar -ziq --foo "$FOO" bla-bla-bla
else
   bar -ziq bla-bla-bla
fi

И всё будет работать как надо. Но хотелось бы избежать дублирования,
постоянные аргументы вызова могут быть громоздкими. Не говоря уж о том, что
если будет несколько условий, код разрастётся в геометрической прогрессии.

Как быть?


Решение не красивое из-за примитивности самого shell-языка:

  $ var="--opt arg 'arg-part1 arg2-part2'"
  $ printarg $var
"printarg"
"--opt"
"arg"
"'arg-part1"
"arg2-part2'"
  $ sh -c "printarg $var"
"printarg"
"--opt"
"arg"
"arg-part1 arg2-part2"

Еще ограничение POSIX shell:

bash# foo=bar
bash# bar=xxx
bash# echo ${${foo}}
bash: ${${foo}}: bad substitution

или

bash# foo1=xxx
bash# foo2=yyy
bash# var=1
bash# echo ${foo${var}}
bash: ${foo${var}}: bad substitution

Для сравнения GNU Make раскрывает "по максимуму":

foo=bar
bar=xxx
$(error $($(foo)))

  $ make
Makefile:3: *** xxx.  Останов.

Интересно почитать про особенную переменную "$@" в двойных кавычках.

Нечто аналогичное делает утилита pathsearch, вот кусочек от туда:

[ -z "$_var" ] && _var=PATH
[ -z "$_delim" ] && _delim=":"

IFS="$_delim"
find=no
for token in `sh -c "echo \$""$_var"`; do## здесь интересно
  if [ -e "$token/$_pattern" ]; then
find=yes
echo "$token/$_pattern"
continue
  fi
  if ls "$token"/$_pattern 2>/dev/null; then
find=yes
  fi
done

[ $find = yes ] && exit 0 || exit 1

Вы можете передать имя переменной окружения в качестве аргумента утилите,
но раскрыть значение имени хранимого в параметре может следующий shell.

--
С уважением, Александр Гавенко.


--
To UNSUBSCRIBE, email to debian-russian-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Archive: http://lists.debian.org/4cc97cc5.1010...@bifit.com.ua



Re: Подстановка переменн ого числа аргументов

2010-10-28 Thread Oleksandr Gavenko

On 28.10.2010 16:20, Victor Wagner wrote:

On 2010.10.28 at 15:14:51 +0300, Serhiy Storchaka wrote:


Здравствуйте.

Прошу прощения за такой элементарный и не совсем тематический вопрос, но это
наиболее компетентная группа, которую я сейчас читаю.

Задача. В зависимости от некоторых условий необходимо вызвать команду с
дополнительными аргументами или без них. Например:

if somecheck
then
   OPTS="--foo $FOO"
else
   OPTS=""
fi
bar -ziq $OPTS bla-bla-bla

Проблема в том, что $FOO может быть пустым (тогда подставится лишь один
аргумент --foo) или содержать пробелы (тогда подставится больше двух
аргументов).



Можно, конечно, написать:

if somecheck
then
   bar -ziq --foo "$FOO" bla-bla-bla
else
   bar -ziq bla-bla-bla
fi

И всё будет работать как надо. Но хотелось бы избежать дублирования,
постоянные аргументы вызова могут быть громоздкими. Не говоря уж о том, что
если будет несколько условий, код разрастётся в геометрической прогрессии.

Как быть?


Ну во-первых, можно подумать о подстановках вида ${FOO:+--foo "${FOO}"}

Это на тот случай если задача ставится так "Если перемная FOO не пуста,
подставляем ключик --foo "$FOO", иначе не делаем ничего.


Иногда это делает код читабельнее.


Во-вторых, можно подумать об использовании команды set, которая позволит
засунуть нужные параметры на место аргументов шелловского скрипта. И
потом подставлять через "$@" - c cохранением разбиения на аргументы.


Интересная идея, правда не всегда получается:

  bash# set arg "arg-part1 arg-part2"
  bash# printarg "$@"
"printarg"
"arg"
"arg-part1 arg-part2"
  bash# var='arg "arg-part1 arg-part2"'
  bash# set $var
  bash# printarg "$@"##   плохо
"printarg"
"arg"
""arg-part1"
"arg-part2""


В-третьих, почитать доку на специфические возможности используемого
шелла. Может быть в bash или zsh есть специальные удобные средства для
этой цели.


Кто знает отпишите пожалуста!


В-четвертых, можно аккуратно квотить дважды.  В смысле
  OPTS="--foo \"\$FOO\"" или OPTS="--foo \"$FOO\"" (почувстуйте разницу
  между этими двумя вариантами.


Не до конца работает:

  $ var="--opt arg 'arg-part1 arg2-part2'"
  $ printarg $var
"printarg"
"--opt"
"arg"
"'arg-part1"
"arg2-part2'"

Что бы заставить работать надо:

  $ sh -c "printarg $var"
"printarg"
"--opt"
"arg"
"arg-part1 arg2-part2"

--
С уважением, Александр Гавенко.


--
To UNSUBSCRIBE, email to debian-russian-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Archive: http://lists.debian.org/4cc980bc.6060...@bifit.com.ua



Re: Подстановка переменн ого числа аргументов

2010-10-28 Thread Oleksandr Gavenko

On 28.10.2010 19:17, Serhiy Storchaka wrote:

Peter Pentchev wrote:

On Thu, Oct 28, 2010 at 05:44:31PM +0300, Serhiy Storchaka wrote:

А printarg -- это откуда?


Если не ошибаюсь, Олександр имеет ввиду чего-то вроде:

#!/bin/sh
#
# This trivial utility is hereby placed into the public domain.

while [ "$#" -gt 0 ]; do
printf '"%s"\n' "$1"
shift
done

(только-что написал, может, есть какие-то баги :)


Ну зачем же так сурово, можно:

for a in "$@"
do
   printf '"%s"\n' "$a"
done

Я сперва думал, может какая-то встроенная команда для отладки в последнем
баше появилась. Или из какого-нибудь пакета shell-misc, содержащего ещё
несколько полезных скриптов.


Так, только на Си.

Cygwin портит аргументы после вызова программ зависимых от cygwin1.dll
(поведение зависит от значения перем. огруж. CYGWIN), вроде как до main.

Нужно было собрать альтернативным компилятором, что бы узнать
что же там по настоящему передается.

--
С уважением, Александр Гавенко.


--
To UNSUBSCRIBE, email to debian-russian-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Archive: http://lists.debian.org/4cca6fa8.1040...@bifit.com.ua



Re: Подстановка переменн ого числа аргументов

2010-10-29 Thread Oleksandr Gavenko

On 29.10.2010 11:16, Serhiy Storchaka wrote:

Oleksandr Gavenko wrote:

Cygwin портит аргументы после вызова программ зависимых от cygwin1.dll
(поведение зависит от значения перем. огруж. CYGWIN), вроде как до main.


Это вынужденные костыли, не нужно винить Cygwin за его помощь убогим. Любая
программа под WinDos вынуждена сама портить свои аргументы.


Нужно было собрать альтернативным компилятором, что бы узнать
что же там по настоящему передается.


Если запустите не через bash#, а через C:\>  -- результат будет другим.


Не критикую Cygwin. Нужно было побороть "умность" Cygwin.

http://thread.gmane.org/gmane.emacs.help/73810
http://thread.gmane.org/gmane.os.cygwin/122538

Теперь если CYGWIN=noglob из argv удаляются '\', а если убрать 'noglob',
то из argv удаляются '{}'. В любом случае плохо, надо дебажить.

Но мы же не об этом ))

--
С уважением, Александр Гавенко.


--
To UNSUBSCRIBE, email to debian-russian-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Archive: http://lists.debian.org/4cca92a4.8020...@bifit.com.ua