Bash-скрипт для получения и повторного цитирования параметров - PullRequest
91 голосов
/ 15 января 2009

Я пытаюсь получить цитируемые параметры bash-скрипта для безопасного получения вложенным скриптом. Есть идеи?

test.sh

#!/bin/bash
echo $*
bash myecho.sh $*

myecho.sh

#!/bin/bash
 echo $1
 echo $2
 echo $3
 echo $4

Пример:

bash test.sh aaa bbb '"ccc ddd"'

Результат:

aaa bbb "ccc ddd"
aaa
bbb
"ccc
ddd"

Требуемый результат

aaa bbb "ccc ddd"
aaa
bbb
ccc ddd

Ответы [ 2 ]

136 голосов
/ 21 октября 2010

Вы хотите использовать «$ @» (в кавычках в долларах) для передачи параметров в индекс. Вот так ....

ls-color.sh:

#!/bin/bash
/bin/ls --color=auto "$@"    # passes though all CLI-args to 'ls'


А почему .....

со страницы руководства Bash :

$* - Расширяется до позиционных параметров, начиная с единицы. когда расширение происходит в двойных кавычках, оно расширяется до одного слова со значением каждого параметра, разделенного первым символом специальная переменная IFS. То есть "$*" эквивалентно "$1c$2c...", где c - первый символ значения IFS переменная. Если IFS не установлен, параметры разделяются пробелами. Если IFS имеет значение null, параметры объединяются без промежуточных разделителей.

$@ - Расширяется до позиционных параметров, начиная с единицы. когда расширение происходит в двойных кавычках, каждый параметр расширяется до отдельное слово То есть "$@" эквивалентно "$1" "$2" ... Если расширение в двойных кавычках происходит в слове, расширение Первый параметр соединяется с начальной частью оригинала слово, а расширение последнего параметра соединяется с последним часть оригинального слова. Когда нет позиционных параметров, "$@" и $@ расширяются до нуля (т.е. они удаляются).


Настройка некоторых демонстрационных скриптов ...

echo 'echo -e "\$1=$1\n\$2=$2\n\$3=$3\n\$4=$4"' > echo-params.sh
echo './echo-params.sh $*' > dollar-star.sh
echo './echo-params.sh $@' > dollar-at.sh
echo './echo-params.sh "$*"' > quoted-dollar-star.sh
echo './echo-params.sh "$@"' > quoted-dollar-at.sh
chmod +x *.sh

"$@" - цитируемый доллар-at - это преобразование идентификатора для повторной передачи аргументов в подоболочку (~ 99% времени, это то, что вы хотели делать):

./quoted-dollar-at.sh aaa '' "'cc cc'" '"ddd ddd"'
  # $1= aaa
  # $2=            
  # $3= 'cc cc'
  # $4= "ddd ddd"

"$*" - цитируемая доллар-звезда разбивает аргументы в одну строку (~ 1% времени, когда вы действительно хотите это поведение, например, в условном выражении: if [[ -z "$*" ]]; then ...):

./quoted-dollar-star.sh aaa '' "'cc cc'" '"ddd ddd"'
  # $1= aaa  'cc cc' "ddd ddd"   
  # $2=                     
  # $3=             
  # $4=

$* / $@ - без кавычек обе формы убирают один уровень кавычек и интерпретируют пробелы из базовых строк, но игнорируют кавычки (почти всегда это ошибка):

./dollar-star.sh aaa '' "'cc cc'" '"ddd ddd"'
  # $1= aaa
  # $2= 'cc                  
  # $3= cc'
  # $4= "ddd

./dollar-at.sh aaa '' "'cc cc'" '"ddd ddd"'
  # $1= aaa
  # $2= 'cc
  # $3= cc'
  # $4= "ddd

Если вы хотите повеселиться, вы можете использовать "$ @", чтобы вкладывать вещи настолько глубоко, насколько вы хотите, толкая и выталкивая элементы из стека args, если хотите.

function identity() {
  "$@"
}
set -x
identity identity identity identity identity echo Hello \"World\"
# + identity identity identity identity identity echo Hello '"World"'
# + identity identity identity identity echo Hello '"World"'
# + identity identity identity echo Hello '"World"'
# + identity identity echo Hello '"World"'
# + identity echo Hello '"World"'
# + echo Hello '"World"'
# Hello "World"
66 голосов
/ 15 января 2009
#!/bin/bash
echo $*
bash myecho.sh "$@"

Обратите внимание, что конструкция "$ @" не относится к bash и должна работать с любой оболочкой POSIX (по крайней мере, с dash). Также обратите внимание, что, учитывая желаемый результат, вам вообще не нужен дополнительный уровень цитирования. И.Е. просто вызовите вышеуказанный скрипт как:

./test.sh 1 2 "3 4"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...