"Bash:

Quiero que esta function devuelva una palabra aleatoria si no hay arguments de command-line.

Estoy modificando el generador de palabras aleatorias de linuxconfig.org para que se ejecute incluso cuando # $ -ne 1.

function random-word { if [ $# -eq 0 ] ; then echo "I only take one argument, dummy" # previously was exit 0 fi # Constants X=0 ALL_NON_RANDOM_WORDS=/usr/share/dict/words # total number of non-random words available non_random_words=`cat $ALL_NON_RANDOM_WORDS | wc -l` # while loop to generate random words # number of random generated words depends on supplied argument while [ $X -lt "$1" ] do random_number=`od -N3 -An -i /dev/urandom | awk -vf=0 -vr="$non_random_words" '{printf "%i\n", f + r * $1 / 16777216}'` sed `echo $random_number`"q;d" $ALL_NON_RANDOM_WORDS let "X = X + 1" done 

La instrucción se ejecuta, pero hay un error bash:

 $ bob I only take one argument, dummy bash: [: : integer expression expected 

¿Cómo soluciono esto para que no se muestre el error bash?

Solutions Collecting From Web of ""Bash:"

while [ $X -lt "$1" ] se está evaluando incluso cuando no hay $ 1.

Mueva el rest del código a un bloque else para que esto no suceda.

 function random-word { # from linuxconfig.org if [ $# -eq 0 ] then echo "I need an argument, dummy" # To be extra friendly, give them a random word. echo "Here's a random word:" random-word 1 else # Constants X=0 ... sed `echo $random_number`"q;d" $ALL_NON_RANDOM_WORDS let "X = X + 1" done fi } 

No necesitas un bloque else . Y no necesita fallar si recibe más de un argumento. Solo necesitas fallar si no obtienes una discusión y luego puedes ignorar todo lo demás o renunciar si no obtienes al less una.

 set -- "${1?ERR: Where\'s my argument?!?!}" 

Esa statement hace todo eso. Esto hace lo mismo pero también falla si el primer argumento es solo '' nullstring:

 set -- "${1:?ERR: Where\'s my argument?!?!}" 

Por supuesto, si el punto es ser una function de shell llamada desde un shell interactivo, esto también puede matar el shell interactivo, por lo que puede hacer:

 (: "${1:?Where\'s my argument?}") || return && set -- "$1" 

… que manejará eso también. Pero, en mi opinión, una function de shell nunca debe afectar a un shell interactivo a less que sea absolutamente necesario, como si necesitara modificar una variable de shell actual o algo así. Y así, mejor que lo anterior sería declarar la function como una subshell, como:

 fn() (set -- "${1:?Where\'s my argument?}" && echo "$1") 

…hace.

Otra forma de hacerlo es aceptar todos los arguments y concatenarlos, por lo que todos los arguments solo se tratan como uno en todos los casos. Puedes hacer eso como:

 fn() ( : "${1:?ERR: Where\'s my argument?}" set -- "$*" && echo "$1" ) fn '' ; fn here are a lot of arguments that will all be treated as one ###OUTPUT### sh: line 2: 1: ERR: Where's my argument? here are a lot of arguments that will all be treated as one 

Personalmente, no me gusta mucho el sh: line 2: 1: bit que generalmente ocurre, al less no en shells interactivos. Normalmente guardo un CTRL+V CTRL+M antes de ERR: por lo tanto, regresa al encabezado de la línea en un terminal y escribe sobre ese bit, pero aún muestra la información más útil en un logging. Me gusta:

 fn() ( : "${1:?^MERR: Where\'s my argument?}" set -- "$*" && echo "$1" ) fn ; fn 2>&1 | cat -A ###OUTPUT### ERR: Where's my argument? sh: line 2: 1: ^MERR: Where's my argument?$