2011-07-06 9 views
6

私は本質的に、別のマシン上の同じ名前の実行可能ファイルのラッパーであるスクリプトを持っています。たとえば、ここでprintfを折り返します。私の現在のスクリプトは次のようになります:sshがシェルスクリプトパラメータを破棄しないようにする

残念ながら、引数の1つにスペースが含まれていると、これが壊れます。私は同じ出力を与えるために、次のコマンドを期待する。:

~$ ./wrap_printf "%s_%s" "hello world" "1" 
hello_world1_ 
~$ printf "%s_%s" "hello world" "1" 
hello world_1 

(エスケープ)改行が含まれる場合、問題はさらに悪化します。どのように私はここで私の議論から適切に脱出するだろうか?

答えて

5
#!/bin/sh 
QUOTE_ARGS='' 
for ARG in "[email protected]" 
do 
    QUOTE_ARGS="${QUOTE_ARGS} '${ARG}'" 
done 
ssh [email protected] "${QUOTE_ARGS}" 

これはスペースで使用できます。引数に埋め込まれた一重引用符がある場合は機能しません。ピーター・リヨンからの回答をもとに

+0

ご利用いただきありがとうございます。引用問題を修正する追加の回答を投稿します。 – Ondergetekende

7

、だけでなく、引数内の引用符を許可する:

#!/bin/bash 
QUOTE_ARGS='' 
for ARG in "[email protected]" 
do 
    ARG=$(printf "%q" "$ARG") 
    QUOTE_ARGS="${QUOTE_ARGS} $ARG" 
done 

ssh [email protected] "printf ${QUOTE_ARGS}" 

これは改行を除いて、私はこれまでテストしたすべてのために動作します:

$ /tmp/wrap_printf "[-%s-]" "hello'\$t\"" 
[-hello'$t"-] 
+0

改行でもうまくいくように思えます(ただし、改行は間違った場所に表示された場合、端末上で奇妙な表示の奇妙な原因になります) – Glyph

2

は、右引用の取得かなり難しく、bashで(一般的で頑強な方法で)ほぼ不可能です。

使用されたPerl:

#!/usr/bin/perl 
use Net::OpenSSH; 
my $ssh = Net::OpenSSH->new('[email protected]'); 
$ssh->system('printf', @ARGV); 
0

Koertとピーター・ライアンは、sshはこちらラッパーからの回答に基づいて、私はそれを「sshsystem」と呼びます。 (https://gist.github.com/4672115でもご利用いただけます)

#!/bin/bash 

# quote command in ssh call to prevent remote side from expanding any arguments 
# uses bash printf %q for quoting - no idea how compatible this is with other shells. 
# http://stackoverflow.com/questions/6592376/prevent-ssh-from-breaking-up-shell-script-parameters 

sshargs=() 

while (($# > 0)); do 
    case "$1" in 
    -[1246AaCfgKkMNnqsTtVvXxYy]) 
     # simple argument 
     sshargs+=("$1") 
     shift 
     ;; 
    -[bcDeFIiLlmOopRSWw]) 
     # argument with parameter 
     sshargs+=("$1") 
     shift 
     if (($# == 0)); then 
      echo "missing second part of long argument" >&2 
      exit 99 
     fi 
     sshargs+=("$1") 
     shift 
     ;; 
    -[bcDeFIiLlmOopRSWw]*) 
     # argument with parameter appended without space 
     sshargs+=("$1") 
     shift 
     ;; 
    --) 
     # end of arguments 
     sshargs+=("$1") 
     shift 
     break 
     ;; 
    -*) 
     echo "unrecognized argument: '$1'" >&2 
     exit 99 
     ;; 
    *) 
     # end of arguments 
     break 
     ;; 
    esac 
done 


# [email protected] 
sshargs+=("$1") 
shift 

# command - quote 
if (($# > 0)); then 
    # no need to make COMMAND an array - ssh will merge it anyway 
    COMMAND= 
    while (($# > 0)); do 
     arg=$(printf "%q" "$1") 
     COMMAND="${COMMAND} ${arg}" 
     shift 
    done 
    sshargs+=("${COMMAND}") 
fi 

exec ssh "${sshargs[@]}" 
関連する問題