#!/bin/sh
echo -n "Enter the raspberry ip address you want to connect:"
read Rasp_id
sshpass -p "the@Donut" ssh -t -X -oStrictHostKeyChecking=no pi@$Rasp_id << E2
echo -e "Enter the case you want to echo\n 1.1 a \n 2.1 b"
read option
case "\$option" in
1)
echo "a"
;;
2)
echo "b"
;;
esac
E2
SSHセッションを開始してからリモートシステムでいくつかの修正を実行するスクリプトを作成していますが、次の構文エラーが発生します。
bash: line 3: syntax error near unexpected token `)'
bash: line 3: ` 1)'
答え1
問題は、stdinの使用を混在させてリモートシステムで実行されるプログラムに入力を提供し、そのプログラムに入力することです。
作成したとおり、次のことが発生します。
- リモートシェルは
echo -e "Enter the case you want to echo\n 1.1 a \n 2.1 b"
stdinから読み込み、それをエコーします。 - リモートシェルは
read option
stdinから読み取り、読み取りを実行します。 read
標準入力から読み込み、case "\$option" in
それのオプションを設定します。- リモートシェルは
1)
stdinから取得し、構文エラーを提供します。
答え2
ここで@icarusの答えを補うために、次のように書くことができます。
#!/bin/sh -
if [ "$#" -eq 0 ]; then
printf >&2 'Enter the raspberry ip address you want to connect to: '
IFS= read -r ip
set -- "$ip"
fi
for ip do
printf >&2 '%s\n' "Connecting to $ip"
SSHPASS=the@Donut sshpass -e \
ssh -oStrictHostKeyChecking=no "pi@$ip" "$(cat << 'EOF'
printf >&2 '%s\n' 'Enter the case you want to echo' \
' 1.1 a' \
' 2.1 b'
IFS= read -r option
case "$option" in
(1) echo a;;
(2) echo b;;
esac
EOF
)"
done
それは:
- 避けてください
echo
(echo -n
/echo -e
は標準のsh+utilities構文ではありません) - 基本的な後処理を避け、生の
read
入力行を読みます。 - ユーザーがホスト名をパラメータとして渡すことができるため、スクリプトを自動化するのが簡単になります。
- ヒントなど現実と一致しない内容を投稿出力stderrのスクリプト(自動化することもできますし、これを行うこともできます
actual_output=$(that-script)
)。 - 公開されたパスワードなので、コマンドラインからパスワードを渡さないでください。このスクリプトには機密情報が含まれているため、アクセスが必要なユーザーにのみパスワードが公開されるようにアクセスを強化する必要があります。
- スクリプトは標準入力ではなくパラメータとして渡されるため、
ssh
スクリプトはまだ標準入力を介してユーザーに照会できます。 cat
これは、終了者()が引用されたhere文書に提供される出力をキャプチャすることによって行われるため、EOF
here文書では拡張されません。- Xサーバーに接続する必要があるコマンドがないため、ここでは不要なX11転送が削除されました。
- また、このスクリプトにはpseudo-ttyが必要ないため、pseudo-ttyも削除しました。
- 不足している引用を追加しました。
上記では、pi
ユーザーのログインシェルが$ip
POSIX-shに似ていると仮定します。