複数のEOFを含む長いスクリプトをコピー/貼り付けようとすると、端末は途中で実行を開始します。

複数のEOFを含む長いスクリプトをコピー/貼り付けようとすると、端末は途中で実行を開始します。

何かをするためにターミナルウィンドウにコピーして貼り付けることができるテキストブロックを作成しようとしています。 (この場合は、MySQLデータベースのメンテナンス用のシステムスクリプトを作成し、毎週実行するタイマーファイルを作成します。スクリプトを作成してプレイブックを有効にします)。

これを端末に貼り付けると、スクリプトの半分(最初のEOFまで)が表示され、それを読んでパスワードを求めるメッセージが表示され、$passが最初のファイルの残りのスクリプトと共に入力されたパスワードがコピーされます。 。

これはブロックです:

sudo sync && echo 'Enter MySQL password for Maintenance user' && read pass && sudo bash -s -c 'cat > "/usr/lib/systemd/system/db-m.service"' << "EOF"
[Service]
Type=oneshot
ExecStart='/usr/bin/mysqlcheck' --auto-repair --optimize --all-databases --force -u'maintenance' -p'$pass'
ExecStart='/usr/bin/sync'
EOF
sudo bash -c 'cat > "/usr/lib/systemd/system/db-m.timer"' << EOF
[Unit]
Description=Weekly database repair and maintenance

[Timer]
OnCalendar=weekly
Persistent=true

[Install]
WantedBy=timers.target
EOF
sudo systemctl daemon-reload && sudo systemctl enable 'db-m.timer' && sudo systemctl start 'db-m' 'db-m.timer' && sudo systemctl status 'db-m' -l

最近3行の後に表示される変数「read pass」と「$pass」を追加しました。

答え1

端末で実行されるシェルは標準入力に貼り付けたスクリプトを受け取り、スクリプト自体は標準入力から読み込みます。ここに衝突があります。スクリプトは独自のコンテンツの一部を読みます。

sudoプロンプトを受け取らないと、次のような状況が発生します。

  1. シェルは、完全なコマンドが得られるまで行全体を読み込みます。最初の行はhereドキュメントを起動するので、シェルはhereドキュメントを読み続けます。
  2. シェルが最初のEOF行に達すると、完全なコマンドがあるのでこれを実行します。
  3. sudo syncそして「echo '...」を実行してください。
  4. read pass走る。入力した行、つまりsudo bash -c …this setを読み込みますpass
  5. sudo sync走る。
  6. シェルは読み取ったコマンドの実行を完了したので、次の入力行を読み込みます[Unit]

複雑な複数行のシェルコードを端末に貼り付けないでください。代わりにクリップボードの内容をシェルスクリプトとして実行する必要がある場合は、以下を使用してください。シェルまたはクリップX11からまたはpbpasteOSXでは。

eval "`xsel`"
eval "`xclip`"
eval "`pbpaste`"

しかし、実際にやるべきことは、それをスクリプトに入れることです。#!/bin/sh上に。

関連情報