Распространение всех аргументов в скрипте оболочки bash

497

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

Например, мое имя script foo.sh и вызывает bar.sh

foo.sh:

bar $1 $2 $3 $4

Как я могу это сделать без явного указания каждого параметра?

Теги:
scripting

7 ответов

931
Лучший ответ

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

Заметим:

$ cat foo.sh
#!/bin/bash
baz.sh $@

$ cat bar.sh
#!/bin/bash
baz.sh "$@"

$ cat baz.sh
#!/bin/bash
echo Received: $1
echo Received: $2
echo Received: $3
echo Received: $4

$ ./foo.sh first second
Received: first
Received: second
Received:
Received:

$ ./foo.sh "one quoted arg"
Received: one
Received: quoted
Received: arg
Received:

$ ./bar.sh first second
Received: first
Received: second
Received:
Received:

$ ./bar.sh "one quoted arg"
Received: one quoted arg
Received:
Received:
Received:
  • 4
    Это делает эту работу для чистого прохождения через кавычки / экранированные строки: Наблюдение: cat rsync_foo.sh #! / Bin / bash echo "$ @" rsync "$ @" ./rsync_foo.sh -n "bar me" bar2 bar me bar2skipping directory bar me Возможно ли иметь скрипт оболочки, который может видеть настоящую оригинальную командную строку с кавычками или экранированными строками?
  • 2
    Как насчет прохождения флагов? Например, './bar.sh --with-stuff'
Показать ещё 7 комментариев
449

Для bash и других оболочек, похожих на Bourne:

java com.myserver.Program "$@"
  • 0
    Это работает для c-shell?
  • 11
    @ Амир: Нет, не для csh . Для всеобщего здравомыслия: не пишите сценарий csh . Но я думаю, что, возможно, $argv:q будет работать в некоторых вариантах csh.
Показать ещё 6 комментариев
71

Используйте "$@" (работает для всех совместимых с POSIX).

[...], bash содержит переменную $@, которая расширяется до всех параметров командной строки, разделенных пробелами.

От Bash на примере.

  • 4
    Так что же, $ @ - это не просто кавычки вокруг $ @, а фактически другая встроенная переменная?
  • 3
    @ben Это единственная переменная, но она требует, чтобы двойные кавычки вокруг нее имели полезное значение, отличное от (ломаного) $* . Я верю, что здесь есть историческое развитие; $* не работал как задумано, поэтому $@ был изобретен, чтобы заменить его; но поскольку правила цитирования являются тем, чем они являются, двойные кавычки вокруг них все еще требуются (или они вернутся к нарушенной семантике $* ).
Показать ещё 4 комментария
23
#!/usr/bin/env bash
while [ "$1" != "" ]; do
  echo "Received: ${1}" && shift;
done;

Просто подумал, что это может быть немного более полезно при попытке проверить, как args входят в ваш script

  • 3
    это определенно не помогло ответить на его вопрос, но это действительно полезно. upvoted!
  • 1
    Он ломается, когда передается пустой параметр. Вы должны проверить на $#
Показать ещё 1 комментарий
5

Мой SUN Unix имеет множество ограничений, даже "$ @" не интерпретировался по желанию. Мое обходное решение - ${@}. Например,

#!/bin/ksh
find ./ -type f | xargs grep "${@}"

Кстати, мне пришлось иметь этот конкретный script, потому что мой Unix также не поддерживает grep -r

4

Я понимаю, что это было хорошо ответили, но здесь сравнение между "$ @" $@ "$ *" и $*

Содержание теста script:

# cat ./test.sh
#!/usr/bin/env bash
echo "================================="

echo "Quoted DOLLAR-AT"
for ARG in "$@"; do
    echo $ARG
done

echo "================================="

echo "NOT Quoted DOLLAR-AT"
for ARG in $@; do
    echo $ARG
done

echo "================================="

echo "Quoted DOLLAR-STAR"
for ARG in "$*"; do
    echo $ARG
done

echo "================================="

echo "NOT Quoted DOLLAR-STAR"
for ARG in $*; do
    echo $ARG
done

echo "================================="

Теперь запустите тест script с различными аргументами:

# ./test.sh  "arg with space one" "arg2" arg3
=================================
Quoted DOLLAR-AT
arg with space one
arg2
arg3
=================================
NOT Quoted DOLLAR-AT
arg
with
space
one
arg2
arg3
=================================
Quoted DOLLAR-STAR
arg with space one arg2 arg3
=================================
NOT Quoted DOLLAR-STAR
arg
with
space
one
arg2
arg3
=================================
1

Прекрасно работает, за исключением случаев, когда у вас есть пробелы или экранированные символы. Я не нашел способ захватить аргументы в этом случае и отправить в ssh внутри script.

Это может быть полезно, но так уродливо

_command_opts=$( echo "$@" | awk -F\- 'BEGIN { OFS=" -" } { for (i=2;i<=NF;i++) { gsub(/^[a-z] /,"&@",$i) ; gsub(/ $/,"",$i );gsub (/$/,"@",$i) }; print $0 }' | tr '@' \' )

Ещё вопросы

Сообщество Overcoder
Наверх
Меню