Propagacja wszystkich argumentów w skrypcie powłoki bash

Piszę bardzo prosty skrypt, który wywołuje inny skrypt i muszę propagować parametry z mojego obecnego skryptu do skryptu, który wykonuję.

Na przykład, moja nazwa skryptu to foo.sh i wywołania bar.sh

Foo.sh:

bar $1 $2 $3 $4

Jak mogę to zrobić bez jawnego podawania każdego parametru?

Author: codeforester, 2011-01-28

8 answers

Użyj "$@" zamiast zwykłego $@, jeśli chcesz, aby twoje parametry były przekazywane tak samo.

$ 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:
 1006
Author: Sdaz MacSkibbons,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-19 16:04:57

Dla bash i innych powłok podobnych do Bourne ' a:

java com.myserver.Program "$@"
 454
Author: Chris Johnsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-06 23:00:15

Use "$@" (działa dla wszystkich zgodnych z POSIX ).

[...], bash posiada zmienną"$@", która rozszerza się na wszystkie parametry wiersza poleceń oddzielone spacjami.

From Bash by example .

 74
Author: miku,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-01 13:06:41
#!/usr/bin/env bash
while [ "$1" != "" ]; do
  echo "Received: ${1}" && shift;
done;

Po prostu pomyślałem, że może to być nieco bardziej przydatne podczas próby sprawdzenia, jak args wchodzą do skryptu

 26
Author: Gregory Patmore,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-04 13:38:34

Zdaję sobie sprawę, że zostało to dobrze odebrane, ale oto porównanie między "$@" $@ "$*" oraz $ *

Zawartość skryptu testowego:

# 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 "================================="

Teraz uruchom skrypt testowy z różnymi argumentami:

# ./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
=================================
 17
Author: JDS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-13 19:36:49

Mój SUN Unix ma wiele ograniczeń, nawet "$ @ " nie było interpretowane zgodnie z życzeniem. Moje obejście to ${ @ }. Na przykład,

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

Przy okazji, musiałem mieć ten konkretny skrypt, ponieważ mój Unix również nie obsługuje grep -r

 6
Author: Hampden123,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-07 11:06:43

Działa poprawnie, chyba że masz spacje lub znaki ucieczki. Nie znajduję sposobu na przechwytywanie argumentów w tym przypadku i wysyłanie do ssh wewnątrz skryptu.

To może być przydatne, ale jest takie brzydkie

_command_opts=$( echo "$@" | awk -F\- 'BEGIN { OFS=" -" } { for (i=2;i<=NF;i++) { gsub(/^[a-z] /,"&@",$i) ; gsub(/ $/,"",$i );gsub (/$/,"@",$i) }; print $0 }' | tr '@' \' )
 1
Author: user6650302,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-28 15:16:11

Jeśli umieścisz $@ w cytowanym łańcuchu z innymi znakami, zachowanie jest bardzo dziwne, gdy jest wiele argumentów, tylko pierwszy argument jest zawarty w cudzysłowach.

Przykład:

#!/bin/bash
set -x
bash -c "true foo $@"

Daje:

$ bash test.sh bar baz
+ bash -c 'true foo bar' baz

Ale przypisanie do innej zmiennej najpierw:

#!/bin/bash
set -x
args="$@"
bash -c "true foo $args"

Daje:

$ bash test.sh bar baz
+ args='bar baz'
+ bash -c 'true foo bar baz'
 0
Author: ColinM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-05 17:30:32