2010-02-12 8 views
6

Beim Schreiben eines Bash-Skripts zur Erstellung eines Polaroid-Thumbnails mithilfe von Imagicks convert Befehl. Ich stoße auf ein Problem. Obwohl es mir gelingt, damit umzugehen (eigentlich, weil convert flexibel genug ist), möchte ich immer noch wissen, wie ich das ohne eine solche spezifische Problemumgehung lösen kann.Bash: Leerzeichen in Variablenwert später als Parameter verwendet

Im Grunde wird das bash-Skript einen Titelwert erhalten, der Leerzeichen enthalten kann. Ich möchte diese Beschriftung als Parameter von convert verwenden. Wenn die Beschriftung leer ist (''), verwende ich nicht die Option '-caption' für den Konvertierungsbefehl. Beispiel:

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`

Das echo echos der Wert, der kopiert werden kann, kann in ein Terminal eingefügt und ausgeführt werden. ABER die Bash läuft nicht. Wie kann ich das machen?

HINWEIS: Bei convert, -caption "" die Aufgabe erledigen. Ich weiß das und verwende das derzeit als Arbeit.

Vielen Dank im Voraus für hilft.

EDIT: Von der Antwort, hier ist der Code, der für mich jetzt funktioniert.

... # 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"

Ich hoffe, dass dies für diejenigen, die ähnliche Lösung suchen, nützlich sein wird.

+0

Als eine Seite - Großbuchstaben Variablennamen sind, nach POSIX-Konvention, für Variablen mit Bedeutung für das Betriebssystem oder Shell verwendet. Ihre Skripte sollten ihre eigenen Variablen mit Namen definieren, die mindestens ein Kleinbuchstabe enthalten, um Konflikte mit diesem Namensraum zu vermeiden. Siehe http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html, wenn man bedenkt, dass das Setzen einer regulären Shell-Variablen mit einem Namen, der jede vorhandene Umgebungsvariable überlagert, die letztere überschreibt. –

Antwort

10

Sie werden entry 050 im BASH FAQ lesen möchten:

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

Danke für die Antwort. Ich versuche es und es funktioniert: D ABER nur im Terminal. Als ich es in die Bash-Datei geschrieben habe, ist der Befehl 'ARGS = (" - caption "" $ CAPTION ")' mit der Fehlermeldung './polaroid.sh: 19: Syntax error: "(" unexpected ") fehlgeschlagen was das ist? – NawaMan

+2

Verwenden Sie 'Bash' in Ihrer Shebang-Zeile, nicht' sh' –

+0

Was für eine Schande ?:(Danke für das darauf hinweisend. Ich bekomme es jetzt zur Arbeit.: 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

Das ist nicht anders als das, was ich tue und es funktioniert nicht. Danke trotzdem. – NawaMan

+0

Sind Sie sicher, dass es nicht funktioniert? was funktioniert nicht? – ghostdog74

+0

bin ich mir sicher. Es teilt meine Beschriftung immer noch nach Leerzeichen auf. – NawaMan

1

Backticks um $COMMAND in der letzten Zeile bewirkt, dass das Skript die Ausgabe auszuführen, um zu versuchen Putting des Befehls statt der Befehl selbst.

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

Dies funktioniert:

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

Während diese Lösung gültig ist, ist es nicht praktikabel. Stellen Sie sich vor, wenn ich viel mehr Parameter habe, muss ich ähnlich wie die Beschriftung beispielsweise Hintergrundfarbe, Rahmenfarbe, Rotationsgrad und so weiter verarbeiten. Wir können keine IF für alle fehlenden Parameter erstellen. Danke trotzdem. :-D – NawaMan

2

ein Array verwenden, wie so:

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

Dieses Konstrukt setzt voraus, dass Sie möglicherweise zahlreiche zusätzliche Argumente anhängen gehen werden. Beachten Sie, dass += in einigen älteren bash-Versionen nicht unterstützt wird, die auf Systemen in diesem Feld noch vorhanden sind (insbesondere RHEL4). Für solche älteren Versionen kann es notwendig sein, extra_args=("${extra_args[@]}" -caption "$1") zu schreiben, um sie an ein Array anzuhängen.

Verwandte Themen