Dlaczego nie mogę uzyskać wartości wyjściowych polecenia w tym skrypcie bash?

9

Więc pisałem ten mały skrypt nautilus do transkodowania wideo na mp3:

#! /bin/bash -x

if [ -z "$1" ]
    then
    zenity --warning --text="Error - No file selected !"
    exit 1
fi

BASEFILENAME=${1%.*}

exec ffmpeg -i "$1" -ab 256k "$BASEFILENAME.mp3" &&

if [ "$?" -eq 0 ]
    then
    zenity --info --text="Converting successful"
    exit
fi

Problem polega na tym, że polecenie ffmpeg zostało pomyślnie wykonane if [ "$?" -eq 0 ]

wydaje się nie zostać wyzwolony. Dlaczego? Czy to &&źle, czy może coś innego?

tesseract
źródło

Odpowiedzi:

13

Jedynym sposobem na osiągnięcie tego stwierdzenia jest execniepowodzenie samego siebie; jeśli się powiedzie, ffmpegpolecenie całkowicie zastępuje powłokę. (Pedantycznie, &&w tym przypadku zawiedzie również, aby w ogóle nie można było do niego dotrzeć.) Nie chcesz exectego, po prostu uruchom go.

geekozaur
źródło
Rozumiem i bez &&polecenia ffmpeg to faktycznie działa. Nadal mam jeszcze jedno pytanie, czy w tym miejscu jest w porządku - czy istnieje sposób, aby wyświetlić gdzieś stdout i stderr ffmpeg bez użycia okna terminala? Jak w zenity fe
tesseract
Chciałbyś uchwycić go z $()konstrukcją do zmiennej, a następnie przekazać tę zmienną do zenity. Uważaj na cytowanie, a zenitymoje doświadczenie wykorzystuje Pango więc trzeba wymienić <, &, >z &lt;, &amp;, &gt;odpowiednio.
geekozaur
5

exec commandOświadczenie zastępuje bieżącą powłokę z command. Oznacza to, że skrypt faktycznie kończy się w linii exec ffmpeg ...; pozostałe wiersze zostaną wykonane, jeśli i tylko wtedy, gdy ffmpegpolecenie nie zostanie znalezione na twojej ŚCIEŻCE (lub nie można go uruchomić z innych powodów).

Możesz uzyskać więcej informacji na temat execwbudowanej wersji bash, pisząc help execw wierszu polecenia bash:

$ help exec
exec: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
    Replace the shell with the given command.

    Execute COMMAND, replacing this shell with the specified program.
    ARGUMENTS become the arguments to COMMAND.  If COMMAND is not specified,
    any redirections take effect in the current shell.
    [...]
Riccardo Murri
źródło
1

Zgodnie z tym exec zastępuje powłokę podanym poleceniem. Więc twój skrypt nigdy nie dociera do poleceń przekraczających exec.

Nie trzeba exec. Wystarczy podać polecenie.

LawrenceC
źródło
0

Możesz zatrzymać execpolecenie, jeśli umieścisz je w podpowłoce:

- exec ffmpeg -i "$1" -ab 256k "$BASEFILENAME.mp3" &&
+ (exec ffmpeg -i "$1" -ab 256k "$BASEFILENAME.mp3") &&
Jeff
źródło
Rozumiem, ale czy &&nadal nie jest źle?
tesseract
Tak. A po co utrzymywać exec?
jmtd