「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

呼び出すシェルがシェルスクリプトに含まれる文字列について何をしているのか心配する必要がない場合は、簡単になります。インラインスクリプトの周りに一重引用符を使用し、そのコマンドラインから必要な引数を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[@]}"

または、これらすべてのパラメータの内容をシェルコードとして含めたい場合:

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"

ここでshquote構文のパラメータを参照しますsh(パラメータを内部にラップしてからに'...'変更)。''\''


関連情報