¿Cómo puedo pasar un argumento de línea de comando a un script de shell?

243

Sé que los scripts de shell simplemente ejecutan comandos como si se ejecutaran en el símbolo del sistema. Me gustaría poder ejecutar scripts de shell como si fueran funciones ... Es decir, tomar un valor de entrada o una cadena en el script. ¿Cómo me acerco a hacer esto?

Pablo
fuente

Respuestas:

199

El comando de shell y los argumentos a ese comando aparecerá como numeradas variables de shell: $0tiene el valor de cadena del comando en sí, algo así como script, ./script, /home/user/bin/scripto lo que sea. Cualquier argumento aparecen como "$1", "$2", "$3"y así sucesivamente. El recuento de argumentos está en la variable de shell "$#".

Las formas comunes de lidiar con esto implican comandos de shell getoptsy shift. getoptses muy parecido a la getopt()función de biblioteca C. shiftmueve el valor de $2to $1, $3to $2, etc. $#se decrementa Code termina mirando el valor de "$1", haciendo cosas usando un case... esacpara decidir sobre una acción, y luego haciendo un shiftpara pasar $1al siguiente argumento. Solo tiene que examinarlo $1, y tal vez $#.

Bruce Ediger
fuente
66
el C getopt()es un estándar extremadamente establecido, pero el getoptejecutable no es el mismo en la distribución / plataforma. Ahora soy un getoptsusuario totalmente convertido , ya que es un estándar POSIX. Funciona muy bien dashtambién, que es mi shell de script preferido
JM Becker
165

Puede acceder a los argumentos pasados ​​con $ndónde nestá el número de argumento - 1, 2, 3, .... Pasa los argumentos como lo haría con cualquier otro comando.

$ cat myscript
#!/bin/bash
echo "First arg: $1"
echo "Second arg: $2"
$ ./myscript hello world
First arg: hello
Second arg: world
Kevin
fuente
27
$/shellscriptname.sh argument1 argument2 argument3 

También puede pasar la salida de un script de shell como argumento a otro script de shell.

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

Dentro de la secuencia de comandos de shell puede acceder a argumentos con números como $1para el primer argumento y $2para el segundo argumento y así sucesivamente.

Más sobre argumentos de shell

Balaswamy vaddeman
fuente
18

La forma

$ ./script.sh "$@" 

Es el más conveniente para argv. El delimitador arg es un espacio en blanco, pero se puede cambiar. No recuerdo cómo fuera de lugar. Luego usa

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

para controlar el flujo. Por lo general, no abrazo getopts si case ... esaces suficiente.

user400344
fuente
14

En un script bash, personalmente me gusta usar el siguiente script para establecer parámetros:

#!/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"

Con esta estructura, no confiamos en el orden de los parámetros, ya que estamos definiendo una letra clave para cada uno de ellos. Además, la función de ayuda se imprimirá todas las veces que los parámetros se definan incorrectamente. Es muy útil cuando tenemos muchos scripts con diferentes parámetros para manejar. Funciona de la siguiente manera:

$ ./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
fuente
13
./myscript myargument

myargumentse vuelve $1adentro myscript.

vimdude
fuente
5

En el script de shell; se convierte en el nombre de la variable $ 1. La segunda palabra se convierte en el nombre de la variable $ 2 y así sucesivamente.

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

Puede encontrar más en el manual de shell (sh) en http://heirloom.sourceforge.net/sh/sh.1.html

Fuego en el cielo
fuente
2
bienvenido a U&L, esto casi no agrega nada a la respuesta ya dada.
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
Yogesh
fuente
3
1) innecesario 2> /dev/null, 2) no agrega nada a las respuestas existentes.
xenoid