Jak mogę przekazać argument wiersza poleceń do skryptu powłoki?

241

Wiem, że skrypty powłoki uruchamiają polecenia tak, jakby były wykonywane w wierszu polecenia. Chciałbym móc uruchamiać skrypty powłoki tak, jakby były funkcjami ... To znaczy, biorąc wartość wejściową lub ciąg znaków do skryptu. Jak podejść do tego?

Paweł
źródło

Odpowiedzi:

198

Polecenie powłoki oraz wszelkie argumenty do tego polecenia pojawiają się jako ponumerowanych zmienne powłoki: $0ma wartość ciągu samego polecenia, coś podobnego script, ./script, /home/user/bin/scriptczy cokolwiek innego. Wszelkie argumenty pojawiają się "$1", "$2", "$3"i tak dalej. Liczba argumentów znajduje się w zmiennej powłoki "$#".

Typowe sposoby radzenia sobie z tym obejmują polecenia powłoki getoptsi shift. getoptsjest bardzo podobny do getopt()funkcji biblioteki C. shiftprzenosi wartość $2na $1, $3do $2i tak dalej; $#ulega zmniejszeniu. Kod kończy się na sprawdzeniu wartości "$1", robieniu rzeczy przy użyciu case… w esaccelu podjęcia decyzji o działaniu, a następnie robieniu shiftprzejścia $1do następnego argumentu. Musi to tylko zbadać $1i być może $#.

Bruce Ediger
źródło
6
C getopt()jest niezwykle ugruntowanym standardem, ale getoptplik wykonywalny nie jest taki sam dla dystrybucji / platformy. Jestem teraz w pełni przekonwertowanym getoptsużytkownikiem, ponieważ jest to standard POSIX. Działa świetnie dashrównież z , która jest moją ulubioną powłoką skryptową
JM Becker
164

Możesz uzyskać dostęp do przekazanych argumentów, $ngdzie gdzie njest numer argumentu - 1, 2, 3, .... Przekazujesz argumenty tak jak w przypadku każdego innego polecenia.

$ cat myscript
#!/bin/bash
echo "First arg: $1"
echo "Second arg: $2"
$ ./myscript hello world
First arg: hello
Second arg: world
Kevin
źródło
27
$/shellscriptname.sh argument1 argument2 argument3 

Możesz także przekazać dane wyjściowe jednego skryptu powłoki jako argument do innego skryptu powłoki.

$/shellscriptname.sh "$(secondshellscriptname.sh)"

W skrypcie powłoki można uzyskać dostęp do argumentów o liczbach takich jak $1pierwszy argument i $2drugi argument i tak dalej.

Więcej na temat argumentów powłoki

Balaswamy Vaddeman
źródło
18

Formularz

$ ./script.sh "$@" 

jest najwygodniejszy dla argv. Separator arg jest spacją, ale można go zmienić. Nie pamiętam, jak z ręki. Następnie użyj

 $1, $2, shift, if [ $# -ne 3 ] 

kontrolować przepływ. Zwykle nie przyjmuję getoptów, jeśli case ... esacwystarczy testament.

użytkownik400344
źródło
14

W skrypcie bash osobiście lubię używać następującego skryptu do ustawiania parametrów:

#!/bin/bash

helpFunction()
{
   echo ""
   echo "Usage: $0 -a parameterA -b parameterB -c parameterC"
   echo -e "\t-a Description of what is parameterA"
   echo -e "\t-b Description of what is parameterB"
   echo -e "\t-c Description of what is parameterC"
   exit 1 # Exit script after printing help
}

while getopts "a:b:c:" opt
do
   case "$opt" in
      a ) parameterA="$OPTARG" ;;
      b ) parameterB="$OPTARG" ;;
      c ) parameterC="$OPTARG" ;;
      ? ) helpFunction ;; # Print helpFunction in case parameter is non-existent
   esac
done

# Print helpFunction in case parameters are empty
if [ -z "$parameterA" ] || [ -z "$parameterB" ] || [ -z "$parameterC" ]
then
   echo "Some or all of the parameters are empty";
   helpFunction
fi

# Begin script in case all parameters are correct
echo "$parameterA"
echo "$parameterB"
echo "$parameterC"

W tej strukturze nie polegamy na kolejności parametrów, ponieważ definiujemy kluczową literę do każdego z nich. Ponadto funkcja pomocy będzie drukowana za każdym razem, gdy parametry zostaną źle zdefiniowane. Jest to bardzo przydatne, gdy mamy do czynienia z wieloma skryptami o różnych parametrach. Działa w następujący sposób:

$ ./myscript -a "String A" -b "String B" -c "String C"
String A
String B
String C

$ ./myscript -a "String A" -c "String C" -b "String B"
String A
String B
String C

$ ./myscript -a "String A" -c "String C" -f "Non-existent parameter"
./myscript: illegal option -- f

Usage: ./myscript -a parameterA -b parameterB -c parameterC
    -a Description of what is parameterA
    -b Description of what is parameterB
    -c Description of what is parameterC

$ ./myscript -a "String A" -c "String C"
Some or all of the parameters are empty

Usage: ./myscript -a parameterA -b parameterB -c parameterC
    -a Description of what is parameterA
    -b Description of what is parameterB
    -c Description of what is parameterC
Rafael Muynarsk
źródło
13
./myscript myargument

myargumentzostaje w $1środku myscript.

vimdude
źródło
5

W skrypcie powłoki; staje się nazwą zmiennej $ 1. Drugie słowo staje się nazwą zmiennej $ 2 i tak dalej.

cat << 'EOF' > test
echo "First arg: $1"
echo "Second arg: $2"
echo "List of all arg: $@"
EOF
sh test hello world

Więcej można znaleźć w podręczniku powłoki (sh) na stronie http://heirloom.sourceforge.net/sh/sh.1.html

Ogień na niebie
źródło
2
witamy w U&L, to prawie nic nie dodaje do już udzielonej odpowiedzi.
Archemar
0
#!/bin/bash
echo "First arg: $1"
echo "Second arg: $2"
echo "Your First Argument was $1 & Second Argument was $2" 2> /dev/null

------------------------------------------------------------------------

./scriptname.sh value1 value2
Jogesh
źródło
3
1) niepotrzebne 2> /dev/null, 2) nie dodaje niczego do istniejących odpowiedzi.
ksenoid