Skip to main content
missing quotes, replace confusing $@ with $1 here.
Source Link
Stéphane Chazelas
  • 584.6k
  • 96
  • 1.1k
  • 1.7k

Quote it again:

if [ "$#" -eq 1 ] ; then
    echo "   Playing..." "$1"
    sshpass -p "$passwd" ssh [email protected] -p "$port" "play '$1'"
else
    echo "  No Input audio file."
fi

The thing is that the first layer of quotes, the "$@" are expanded when you run the sshpass command. So by the time you log in, launch the remote shell and execute play, you have an unquoted string, so your script chokes on whitespace. By enclosing it in a second layer of quotes, you ensure that it is passed quoted to the remote command.

This should work assuming that i) the remote machine is running sh or bash or a similar shell and ii) your file names don't contain single quotes. To make it truly robust, please see How to execute an arbitrary simple command over ssh without knowing the login shell of the remote user?.

For properly quoting an arbitrary string (or even a list of arbitrary strings so you can pass more than one argument to play) in the sh syntax, we can use that shquote() function mentioned there:

shquote() {
  LC_ALL=C awk -v q=\' -v b='\\' '
    BEGIN{
      for (i=1; i<ARGC; i++) {
        gsub(q, q b q q, ARGV[i])
        printf "%s ", q ARGV[i] q
      }
      print ""
      exit
    }' "$@"
}
if [ "$#" -ge 1 ] ; then
    echo "   Playing..." "$@"
    sshpass -p "$passwd" ssh [email protected] -p "$port" "play $(shquote "$@")"
else
    echo "  No Input audio file."
fi

It would quote Sgt. Pepper's lonely hearts club band.flac as 'Sgt. Pepper'\''s lonely hearts club band.mp3' which is correct for sh (and evil';reboot;: '.flac as 'evil'\'';reboot;: '\''.flac' instead of rebooting the remote machine (do you have to run that play command as root?)).

Quote it again:

if [ "$#" -eq 1 ] ; then
    echo "   Playing..." "$1"
    sshpass -p "$passwd" ssh [email protected] -p "$port" "play '$1'"
else
    echo "  No Input audio file."
fi

The thing is that the first layer of quotes, the "$@" are expanded when you run the sshpass command. So by the time you log in, launch the remote shell and execute play, you have an unquoted string, so your script chokes on whitespace. By enclosing it in a second layer of quotes, you ensure that it is passed quoted to the remote command.

This should work assuming that i) the remote machine is running sh or bash or a similar shell and ii) your file names don't contain single quotes. To make it truly robust, please see How to execute an arbitrary simple command over ssh without knowing the login shell of the remote user?.

Quote it again:

if [ "$#" -eq 1 ] ; then
    echo "   Playing..." "$1"
    sshpass -p "$passwd" ssh [email protected] -p "$port" "play '$1'"
else
    echo "  No Input audio file."
fi

The thing is that the first layer of quotes, the "$@" are expanded when you run the sshpass command. So by the time you log in, launch the remote shell and execute play, you have an unquoted string, so your script chokes on whitespace. By enclosing it in a second layer of quotes, you ensure that it is passed quoted to the remote command.

This should work assuming that i) the remote machine is running sh or bash or a similar shell and ii) your file names don't contain single quotes. To make it truly robust, please see How to execute an arbitrary simple command over ssh without knowing the login shell of the remote user?.

For properly quoting an arbitrary string (or even a list of arbitrary strings so you can pass more than one argument to play) in the sh syntax, we can use that shquote() function mentioned there:

shquote() {
  LC_ALL=C awk -v q=\' -v b='\\' '
    BEGIN{
      for (i=1; i<ARGC; i++) {
        gsub(q, q b q q, ARGV[i])
        printf "%s ", q ARGV[i] q
      }
      print ""
      exit
    }' "$@"
}
if [ "$#" -ge 1 ] ; then
    echo "   Playing..." "$@"
    sshpass -p "$passwd" ssh [email protected] -p "$port" "play $(shquote "$@")"
else
    echo "  No Input audio file."
fi

It would quote Sgt. Pepper's lonely hearts club band.flac as 'Sgt. Pepper'\''s lonely hearts club band.mp3' which is correct for sh (and evil';reboot;: '.flac as 'evil'\'';reboot;: '\''.flac' instead of rebooting the remote machine (do you have to run that play command as root?)).

missing quotes, replace confusing $@ with $1 here.
Source Link
Stéphane Chazelas
  • 584.6k
  • 96
  • 1.1k
  • 1.7k

Quote it again:

if [ $#"$#" -eq 1 ] ; then
    echo "   Playing..." "$@""$1"
    sshpass -p $passwd "$passwd" ssh [email protected] -p $port "$port" play"play "'$@'"'$1'"
else
    echo "  No Input audio file."
fi

The thing is that the first layer of quotes, the "$@" are expanded when you run the sshpass command. So by the time you log in, launch the remote shell and execute play, you have an unquoted string, so your script chokes on whitespace. By enclosing it in a second layer of quotes, you ensure that it is passed quoted to the remote command.

This should work assuming that i) the remote machine is running sh or bash or a similar shell and ii) your file names don't contain single quotes. To make it truly robust, please see How to execute an arbitrary simple command over ssh without knowing the login shell of the remote user?.

Quote it again:

if [ $# -eq 1 ] ; then
    echo "   Playing..." "$@"
    sshpass -p $passwd  ssh [email protected] -p $port  play "'$@'"
else
    echo "  No Input audio file."
fi

The thing is that the first layer of quotes, the "$@" are expanded when you run the sshpass command. So by the time you log in, launch the remote shell and execute play, you have an unquoted string, so your script chokes on whitespace. By enclosing it in a second layer of quotes, you ensure that it is passed quoted to the remote command.

This should work assuming that i) the remote machine is running sh or bash or a similar shell and ii) your file names don't contain single quotes. To make it truly robust, please see How to execute an arbitrary simple command over ssh without knowing the login shell of the remote user?.

Quote it again:

if [ "$#" -eq 1 ] ; then
    echo "   Playing..." "$1"
    sshpass -p "$passwd" ssh [email protected] -p "$port" "play '$1'"
else
    echo "  No Input audio file."
fi

The thing is that the first layer of quotes, the "$@" are expanded when you run the sshpass command. So by the time you log in, launch the remote shell and execute play, you have an unquoted string, so your script chokes on whitespace. By enclosing it in a second layer of quotes, you ensure that it is passed quoted to the remote command.

This should work assuming that i) the remote machine is running sh or bash or a similar shell and ii) your file names don't contain single quotes. To make it truly robust, please see How to execute an arbitrary simple command over ssh without knowing the login shell of the remote user?.

added 231 characters in body
Source Link
terdon
  • 252.2k
  • 69
  • 480
  • 718

Quote it again:

if [ $# -eq 1 ] ; then
    echo "   Playing..." "$@"
    sshpass -p $passwd  ssh [email protected] -p $port  play "'$@'"
else
    echo "  No Input audio file."
fi

The thing is that the first layer of quotes, the "$@" are expanded when you run the sshpass command. So by the time you log in, launch the remote shell and execute play, you have an unquoted string, so your script chokes on whitespace. By enclosing it in a second layer of quotes, you ensure that it is passed quoted to the remote command.

This should work assuming that i) the remote machine is running sh or bash or a similar shell and ii) your file names don't contain single quotes. To make it truly robust, please see How to execute an arbitrary simple command over ssh without knowing the login shell of the remote user?.

Quote it again:

if [ $# -eq 1 ] ; then
    echo "   Playing..." "$@"
    sshpass -p $passwd  ssh [email protected] -p $port  play "'$@'"
else
    echo "  No Input audio file."
fi

The thing is that the first layer of quotes, the "$@" are expanded when you run the sshpass command. So by the time you log in, launch the remote shell and execute play, you have an unquoted string, so your script chokes on whitespace. By enclosing it in a second layer of quotes, you ensure that it is passed quoted to the remote command.

Quote it again:

if [ $# -eq 1 ] ; then
    echo "   Playing..." "$@"
    sshpass -p $passwd  ssh [email protected] -p $port  play "'$@'"
else
    echo "  No Input audio file."
fi

The thing is that the first layer of quotes, the "$@" are expanded when you run the sshpass command. So by the time you log in, launch the remote shell and execute play, you have an unquoted string, so your script chokes on whitespace. By enclosing it in a second layer of quotes, you ensure that it is passed quoted to the remote command.

This should work assuming that i) the remote machine is running sh or bash or a similar shell and ii) your file names don't contain single quotes. To make it truly robust, please see How to execute an arbitrary simple command over ssh without knowing the login shell of the remote user?.

Source Link
terdon
  • 252.2k
  • 69
  • 480
  • 718
Loading