在“sh -c”内用双引号引用

在“sh -c”内用双引号引用

我试图让这个引用起作用,但没有成功:

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

所以我尝试了这个:

$ 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.

引用真是让人头疼。

答案1

如果您不必担心调用 shell 对内嵌 shell 脚本的字符串执行什么操作,那就更容易了。您可以在内联脚本周围使用单引号,并将所需的参数传递给其命令行上的 in :

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" "$@"

答案2

也许你的意思是:

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[@]}"

或者,如果您想将所有这些参数的内容嵌入为 shell 代码:

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"

whereshquote在语法中引用其参数sh(将参数包装在内部'...'并更改''\'')。


相关内容