Me encuentro con un problema al pasar un argumento a un comando en un script de Bash.
poc.sh:
#!/bin/bash ARGS='"hi there" test' ./swap ${ARGS}
intercambiar:
#!/bin/sh echo "${2}" "${1}"
La salida actual es:
there" "hi
Cambiando solo poc.sh (ya que creo que swap hace lo que quiero que sea correcto), ¿cómo obtengo poc.sh para pasar “hola allí” y probar como dos argumentos, con “hola ahí” sin comillas?
Si es posible, no use cadenas entre comillas como formato de entrada.
shlex
y shlex
continuación). printf '%q'
, que generará una cadena cotizada por el shell con contenidos de una variable arbitraria, pero no existe equivalente en el estándar POSIX sh. eval
, que tiene importantes problemas de seguridad. Las secuencias delimitadas por NUL son una práctica mucho mejor, ya que pueden representar con precisión cualquier matriz de shell o lista de argumentos posibles sin ambigüedad alguna.
Si obtiene su lista de argumentos de una fuente de entrada generada por el ser humano mediante el uso de comillas de shell, puede considerar utilizar xargs
para analizarlo. Considerar:
array=( ) while IFS= read -r -d ''; do array+=( "$REPLY" ) done < <(xargs printf '%s\0' <<<"$ARGS") swap "${array[@]}"
... colocará el contenido analizado de $ARGS
en la matriz de array
. Si en cambio deseaba leer un archivo, sustituya <<<"$ARGS"
.
Si está intentando escribir un código que cumpla con POSIX sh, esto se vuelve más complicado. (Voy a asumir la entrada de archivos aquí para una complejidad reducida):
# This does not work with entries containing literal newlines; you need bash for that. run_with_args() { while IFS= read -r entry; do set -- "$@" "$entry" done "$@" } xargs printf '%s\n'
Estos enfoques son más seguros que ejecutar xargs ./swap
Si necesita un análisis sintáctico POSIX más preciso que los implementos xargs
, considere usar el módulo Python shlex
lugar:
shlex_split() { python -c ' import shlex, sys for item in shlex.split(sys.stdin.read()): sys.stdout.write(item + "\0") ' } while IFS= read -r -d ''; do array+=( "$REPLY" ) done < <(shlex_split <<<"$ARGS")
Las comillas incorporadas no protegen el espacio en blanco; ellos son tratados literalmente Usa una matriz en bash
:
args=( "hi there" test) ./swap "${args[@]}"
En el shell POSIX, estás atascado usando eval
(que es por lo que la mayoría de las shells admiten matrices).
args='"hi there" test' eval "./swap $args"
Como de costumbre, asegúrese de conocer el contenido de $args
y comprender cómo se analizará la cadena resultante antes de usar eval
.
Este podría no ser el enfoque más sólido, pero es simple y parece funcionar para su caso:
## demonstration matching the question $ ( ARGS='"hi there" test' ; ./swap ${ARGS} ) there" "hi ## simple solution, using 'xargs' $ ( ARGS='"hi there" test' ; echo ${ARGS} |xargs ./swap ) test hi there