![Bash reconoce el argumento de la función como un programa](https://rvso.com/image/1665759/Bash%20reconoce%20el%20argumento%20de%20la%20funci%C3%B3n%20como%20un%20programa.png)
Soy bastante nuevo en la sintaxis de bash y tengo un fragmento de código en mi archivo '.bash_aliases'. Obtiene un número entero como argumento o la letra 'c'; cuando obtiene un número entero, coloca ese número entero en una variable de entorno, que los servidores web pueden utilizar como puerto. Cuando recibe la letra 'c' como entrada, borra la variable.
Cuando intento ejecutar mi comando con un número entero aparece el error
main@linuxWSL:~$ serverp 2000
-bash: [: missing `]'
2000: command not found
y cuando lo intento con la letra 'c' me sale
main@linuxWSL:~$ serverp c
-bash: [: missing `]'
c: command not found
Este es mi código bash:
serverp () {
if [ "$1" = "clear" || "$1" = "c" ]
then
unset PORT
echo -e "\e$CLEAR$GREEN""mWebServer port has been reset!""$CLEAN"
return 0
fi
export PORT="$1"
}
¿Alguien me puede ayudar? ¡Gracias!
Respuesta1
[
no es una palabra clave en Bash que haría que el analizador de shell interprete el resto de la línea de comando de manera diferente. [
es un comando como cat
o echo
. [
(como echo
) es una función incorporada en Bash, pero esto solo significa que se puede ejecutar sin generar un proceso adicional; aún se comporta como un comando.
Y para ser claros: [ … ]
no forma parte de if … then …
la sintaxis. if
simplemente prueba el estado de salida de algún código: if true; then …
es válido, if sleep 5; then …
es válido, de manera similar if [ … ]; then …
es válido (si la [ … ]
parte es en sí misma un comando válido).
Probablemente haya un [
ejecutable en su sistema. Intentar type -a [
. Comparar con type -a [[
. Al contrario de [
, [[
es una palabra clave en Bash y hace que el analizador trate las cosas entre [[
y ]]
de manera especial.
[
no es una palabra clave. Correctamente escrito [ … ]
es un comando donde ]
está solo el último argumento. [
requiere ]
como último argumento, de lo contrario se niega a funcionar. Esto es sólo para [ … ]
resaltar como un bloque, como si fuera una sintaxis especial; pero no es una sintaxis especial.
Tu [ "$1" = "clear" || "$1" = "c" ]
es interpretado por el shell [ "$1" = "clear"
y "$1" = "c" ]
conectado con ||
. Entonces hay dos comandos. El primer comando es [ "$1" = "clear"
, [
se ejecuta, no aparece ]
como último argumento, se queja y sale con un estado de salida distinto de cero. Debido al estado distinto de cero y debido a ||
, el shell intenta ejecutar el segundo comando que comienza con lo que "$1"
se expande a. De esta manera, el primer argumento de su script se interpreta como un ejecutable para ejecutar.
Arregla tu [ … || … ]
así:
[ "$1" = "clear" ] || [ "$1" = "c" ]
Este fragmento consta de dosválido [
comandos. Debería hacer lo que quieras.
La nota [[ "$1" = "clear" || "$1" = "c" ]]
es un código funcional, mientras [ "$1" = "clear" || "$1" = "c" ]
que no lo es. Esto se debe a que [[
no es un comando. Es una palabra clave y hace que el analizador de shell trate todo de manera ]]
especial; esto incluye el ||
. Hay otrosdiferencias entre [[
y[
, no los intercambies a ciegas.
El [
soporte integrado en Bash -o
parao(y -a
paray), por lo que esto también funcionará:
[ "$1" = "clear" -o "$1" = "c" ]
Es su código donde ||
(especial para el shell) fue reemplazado por -o
(no especial para el shell). Aunque deberías evitarlo -o
. DeEste artículo:
El binario
-a
y-o
[…] son extensiones XSI del estándar POSIX. Todos están marcados como obsoletos en POSIX-2008. No deben usarse en código nuevo. Uno de los problemas prácticos con[ A = B -a C = D ]
(o-o
) es que POSIX no especifica los resultados de un comandotest
o[
con más de 4 argumentos. Probablemente funcione en la mayoría de los shells, pero no puedes contar con ello. Si tiene que escribir para shells POSIX, entonces debería usar dos comandostest
o[
separados por un&&
operador.
Tenga en cuenta que el artículo detalla -a
, por lo que "un &&
operador en su lugar". En tu caso es -o
y ||
respectivamente. Dos pruebas separadas por un ||
operador es exactamente nuestra solución.
Respuesta2
Es if [ "$1" = "clear" ] || [ "$1" = "c" ]
.