質問

I have the following code:

errorlevel=-1

{ wget "$1" -O "$2" 2>&1; errorlevel=$?; } |\
sed -u 's/^[a-zA-Z\-].*//; s/.* \{1,2\}\([0-9]\{1,3\}\)%.*/\1\n#Downloading... \1%/; s/^20[0-9][0-9].*/#Done./' | \
dlg --progress --percentage=0 --title=Download dialog --text=Starting... --auto-close --auto-kill --button=gtk-cancel

However, regardless of whatever wget returns, I always get -1 in $errorlevel. Seems like $errorlevel isn't modified at all by that statement.

Where am I doing this wrong and how do I fix this?

(PIPESTATUS or set -o pipefail etc. are not usable in this case, otherwise I won't be able to tell if the user has cancelled the operation or not (dlg invokes a GUI).)

役に立ちましたか?

解決 2

If you do not like the PIPESTATUS solution of @devnull (which I would understand; after all it binds you closely to the bash and other shells which support that feature), you maybe can do it like this:

{
  wget "$1" -O "$2" 2>&1
  errorlevel=$?
  echo "Now I'm using the variable errorlevel:" 1>&2  # redirect to avoid piping this into sed below
  case $errorlevel in
    143) # segfault?
      echo "Whoa!" 1>&2
      ;;
    # ...
  esac
} | sed -u 's/^[a-zA-Z\-].*//; s/.* \{1,2\}\([0-9]\{1,3\}\)%.*/\1\n#Downloading... \1%/; s/^20[0-9][0-9].*/#Done./' | \
dlg --progress --percentage=0 --title=Download dialog --text=Starting... --auto-close --auto-kill --button=gtk-cancel

You also can consider to use a fifo to split the piping into two commands:

mkfifo /tmp/ff
cat /tmp/ff/ | sed ... | dlg ... &
wget ... > /tmp/ff
errorlevel=$?
rm /tmp/ff

This way you might have trouble capturing the output of the sed ... | dlg ... pipe, but maybe that is not interesting for you.

And of course you can step away from piping and capture the wget output first, and then start the sed and dlg if and only if wget was successful:

wgetOutput=$(wget ...)
errorlevel=$?
case $errorlevel in
  0)
    echo "$wgetOutput" | sed ... | dlg ...
    ;;
  # add other cases here for handle errors of wget.
esac

But this can only work for limited amounts of output from wget. It won't work for streams of course.

他のヒント

I always get -1 in $errorlevel.

That's because you are setting the variable in a subshell.

The changes made to the variable are lost upon exiting the subshell.

You might want to look at ${PIPESTATUS[@]}.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top