0

I'm trying to make this quoting work, but no success :

export perl_script='$| = 1;s/\n/\r/g if $_ =~ /^AV:/;s/Saving state/\nSaving state/'
mpv="command mpv"
mpvOptions='--geometry 0%:100%'
args=("$@")
$ sh -c "$mpv $mpvOptions ${args[*]} 2>&1 | perl -p -e $perl_script | tee ~/mpv_all.log"
syntax error at -e line 1, at EOF
Execution of -e aborted due to compilation errors.
sh: 1: =: not found
sh: 1: s/n/r/g: not found
sh: 1: s/Saving: not found

So I tried this :

$ sh -c "$mpv $mpvOptions ${args[*]} 2>&1 | perl -p -e \"perl_script\" | tee ~/mpv_all.log"
Unknown regexp modifier "/h" at -e line 1, at end of line
Execution of -e aborted due to compilation errors.

Quoting is such a pain in the neck.

  • 1
    You probably want single quotes, like sh -c "$mpv ${args[*]} 2>&1 | perl -p -e '$perl_script' | tee ~/mpv_all.log". Why does everything need to be inside sh -c? – jw013 Apr 8 at 19:44
  • @jw013 Because, then I want to use nohup sh -c .... – SebMa Apr 8 at 19:48
  • @jw013 Can you please convert your comment into an answer ? – SebMa Apr 8 at 19:54
  • My comment was just a quick and dirty suggestion to get you going since all it took was adding two keystrokes. The two answers that have been posted are both far more robust than my comment and I would recommend using one of them instead. – jw013 Apr 8 at 19:58
  • @jw013 I like "your quick and d.... suggestion" because it solved my pb. without having to rewrite anything in my code, that's why I'd like yout to convert your comment into an answer. – SebMa Apr 8 at 20:02
2

It's easier if you don't have to bother about what the calling shell does to the string which is the in-line shell script. You can use single quotes around the in-line script and pass the needed argument to in on its command line:

perl_script='$| = 1;s/\n/\r/g if $_ =~ /^AV:/;s/Saving state/\nSaving state/'

sh -c 'p=$1; shift
       command mpv "$@" 2>&1 |
       perl -pe "$p" |
       tee "$HOME/mpv_all.log"' sh "$perl_script" "$@"
  • Actually, I would but I have another mpvOptions variable. – SebMa Apr 8 at 20:11
  • @SebMa Not in the code in the question... – Kusalananda Apr 8 at 20:13
  • You're absolutely right, I had forgotten it. I've just updated my question with it – SebMa Apr 8 at 20:15
2

Maybe you meant:

export perl_script='
  $| = 1;
  s/\n/\r/g if $_ =~ /^AV:/;
  s/Saving state/\nSaving state/'

mpv=(command mpv)
args=("$@")
sh -c '
  "$@" 2>&1 |
    perl -p -e "$perl_script" | tee ~/mpv_all.log
 ' sh "${mpv[@]}" "${args[@]}"

Or if you wanted to embed the content of all those arguments as shell code:

shquote() {
  LC_ALL=C awk -v q=\' '
    BEGIN{
      for (i=1; i<ARGC; i++) {
        gsub(q, q "\\" q q, ARGV[i])
        printf "%s ", q ARGV[i] q
      }
      print ""
    }' "$@"
}

perl_script='
  $| = 1;
  s/\n/\r/g if $_ =~ /^AV:/;
  s/Saving state/\nSaving state/'

mpv=(command mpv)
args=("$@")

sh -c "
  $(shquote "${mpv[@]}" "${args[@]}") 2>&1 |
  perl -p -e $(shquote "$perl_script") | tee ~/mpv_all.log"

Where shquote quotes its argument in sh syntax (wraps arguments inside '...' and change ' to '\'').


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.