2010-02-12 16 views
6

Al escribir una secuencia de comandos bash para ayudar a crear una miniatura de Polaroid con el comando convert de Imagick. Encuentro un problema Aunque me las arreglé para evitar esto (en realidad, porque convert es lo suficientemente flexible), igual quiero saber cómo solucionarlo sin esa solución específica.Bash: espacio en valor variable utilizado más tarde como parámetro

Así que, básicamente, el script bash obtendrá un valor de título que puede contener espacio. Quiero usar ese título como parámetro de convert. Si el título está vacío (''), no usaré la opción '-caption' para el comando de conversión. De esta manera:

CAPTION="Is this Cute?" # The actual value will be tacked from the parameter of this bash. 
IN_FILE="resources/puppy.png" 
OUTFILE="resources/puppy_polaroid.png" 

# If CAPTION is not empty, reformat CAPTION 
if [ "$CAPTION" != "" ]; then CAPTION="-caption \"$CAPTION\""; fi 
# otherwise, do not use '-caption' add all 

COMMAND="convert $CAPTION \"$IN_FILE\" \"$OUTFILE\"" 
echo "Command: $COMMAND" #This echo a value command 
`$COMMAND`

El eco repite el comando de valor que se puede copiar puede pegar en un terminal y ejecutarse. PERO el bash no se ejecuta. ¿Como puedo hacer esto?

NOTA: En caso de convert, -caption "" haga el trabajo. Sé esto y actualmente lo uso como una solución.

Gracias de antemano por su ayuda.

EDIT: De la respuesta, aquí está el código que funciona para mí ahora.

... # Get CAPTION and GRAVITY from parameters 

if [ "$CAPTION" != "" ]; then ARGS_CAPTION=(-caption "$CAPTION"); fi 
if [ "$GRAVITY" != "" ]; then ARGS_GRAVITY=(-gravity "$GRAVITY"); fi 

if [ ! -f "$IN_FILE" ]; then echo "The input file does not exist: '$IN_FILE'"; exit; fi 
if [ "$OUTFILE" == "" ]; then OUTFILE=${IN_FILE%.*}-${IN_FILE#*.}-polaroid.png; fi 

ARGS=("${ARGS_CAPTION[@]}" -thumbnail 480x480 -border 5x5 -pointsize 60 "${ARGS_GRAVITY[@]}" +polaroid -thumbnail 120x120) 
echo convert "${ARGS[@]}" "$IN_FILE" "$OUTFILE"; 
convert "${ARGS[@]}" "$IN_FILE" "$OUTFILE"

Espero que esto sea útil para aquellos que buscan una solución similar.

+0

Como un lado, todos los nombres de variables de mayúsculas son, por convención POSIX, utilizados para variables con significado para el sistema operativo o shell. Sus scripts deben definir sus propias variables con nombres que contengan al menos un carácter en minúsculas para evitar conflictos con este espacio de nombres. Consulte http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html, teniendo en cuenta que establecer una variable de shell regular con un nombre que se superpone a cualquier variable de entorno existente sobrescribirá la última. –

Respuesta

10

Usted querrá leer entry 050 en el BASH FAQ:

I'm trying to put a command in a variable, but the complex cases always fail!

Variables hold data. Functions hold code. Don't put code inside variables! There are many situations in which people try to shove commands, or command arguments, into variables and then run them. Each case needs to be handled separately.

...

  1. I'm constructing a command based on information that is only known at run time

The root of the issue described above is that you need a way to maintain each argument as a separate word, even if that argument contains spaces. Quotes won't do it, but an array will. (We saw a bit of this in the previous section, where we constructed the addrs array on the fly.)

If you need to create a command dynamically, put each argument in a separate element of an array. A shell with arrays (like Bash) makes this much easier. POSIX sh has no arrays, so the closest you can come is to build up a list of elements in the positional parameters. Here's a POSIX sh version of the sendto function from the previous section:

+0

Gracias por responder. Lo intento y funciona: D PERO solo en la terminal. Cuando lo puse en el archivo bash, el comando 'ARGS = (" - leyenda "" $ CAPTION ")' falló con un mensaje de error de './polaroid.sh: 19: Error de sintaxis: "(" inesperado'. ¿Sabes? ¿Qué es esto? – NawaMan

+2

Usa 'bash' en tu línea shebang, no' sh'. –

+0

¡Qué lástima! :(Gracias por señalar eso de todos modos. Lo hago funcionar ahora.: D – NawaMan

-1
CAPTION="$1" 
IN_FILE="resources/puppy.png" 
OUTFILE="resources/puppy_polaroid.png" 

case "$CAPTION" in 
    "") CAPTION="-caption ''";; 
    *) CAPTION='-caption "$CAPTION"';; 
esac 

convert $CAPTION "$IN_FILE" "$OUTFILE" 
+0

Esto no es diferente de lo que estoy haciendo y no funciona. Gracias de cualquier manera. – NawaMan

+0

¿estás seguro de que no funciona? ¿qué no funciona? – ghostdog74

+0

Estoy seguro. Todavía dividió mi leyenda por espacios. – NawaMan

1

Poner acentos abiertos en torno $COMMAND en la última línea hace que la secuencia de comandos para intentar ejecutar el salida del comando en lugar de la comando en sí.

$ c='echo hi' 
$ `$c` 
hi: command not found 

esto funcionará:

if [[ "$CAPTION" != "" ]] 
then 
    convert -caption "$CAPTION" "$IN_FILE" "$OUTFILE" 
else 
    convert "$IN_FILE" "$OUTFILE" 
fi 
+0

Si bien esta solución es válida, no es práctica. Imagínese si tengo muchos más parámetros que deba procesar de la misma manera que los subtítulos, por ejemplo, el color de fondo, el color del borde, el grado de rotación, etc. Simplemente no podemos crear IF para todos los parámetros faltantes. Gracias de cualquier manera. :-RE – NawaMan

2

utilizar una matriz, como tan:

#!/bin/bash 
# ^^^ - note the shebang line explicitly using bash, not /bin/sh 

CAPTION="Is this Cute?" # The actual value will be tacked from the parameter of this bash. 
IN_FILE="resources/puppy.png" 
OUTFILE="resources/puppy_polaroid.png" 

extra_args=() 
if [[ $CAPTION ]] ; then 
    extra_args+=(-caption "$1") 
fi 
convert "${extra_args[@]}" "$INFILE" "$OUTFILE" 

Esta construcción supone que usted está potencialmente va a estar añadiendo numerosos argumentos adicionales. Tenga en cuenta que += no está soportado en algunas versiones anteriores de bash que todavía están presentes en sistemas desplegados en el campo (sobre todo RHEL4). Para versiones anteriores, puede ser necesario escribir extra_args=("${extra_args[@]}" -caption "$1") para anexar a una matriz.

Cuestiones relacionadas