echo以降、上記のコマンドの出力は次のようになります。
# echo systemctl\ {restart,status}\ sshd\;
systemctl restart sshd; systemctl status sshd;
出力を端末に貼り付けても、コマンドは引き続き機能します。ただし、コマンドを直接実行しようとすると、次の結果が表示されます。
# systemctl\ {restart,status}\ sshd\;
bash: systemctl restart sshd;: command not found...
2つの質問があります。
- この代替方法と拡張方法は正確に何ですか? (それで私はそれを調べて、それについてもっと学び、正しく使用する方法を学ぶことができます)。
- 私がここで何を間違っているのか?なぜ動作しないのですか?
答え1
それは形ですサポート拡張シェルで完了しました。支柱の拡張という概念は正しいですが、ここで使用されている方法は正しくありません。これを行うとき:
systemctl\ {restart,status}\ sshd\;
シェルはこれをsystemctl restart sshd;
長いコマンドとして解釈して実行しようとしますが、この方法で実行するバイナリを見つけることができません。この段階では、シェルは引数を使用して完全なコマンドを作成する前に、コマンドラインのエントリにタグを付けようとしましたが、まだそのようなことは発生していません。
これらの既知の拡張値の場合は使用できますeval
が、それでも安全ですが、それを使用して拡張したいものが何であるかを確認してください。
eval systemctl\ {restart,status}\ sshd\;
for
しかし、私は行を書いたり、次を使うよりもループを使いたいと思いますeval
。
for action in restart status; do
systemctl "$action" sshd
done
答え2
これは…支柱の拡張(ラベルに示すように)。
私がここで何を間違っているのか?なぜ動作しないのですか?
たとえば、Bashでコマンドラインを読み取って実行する手順を考えてみましょう。
- 一行を読む
- 可能な複合コマンドをコンポーネント単純コマンドに解析
- 簡単なコマンドに対するさまざまな拡張(中括弧拡張、ワードセパレータ、ワイルドカードなど)
- その後、単純なコマンドが実行されます(明確にするために他の手順は省略されています)。
あなたがしたいことは(3)の(2)に影響を与えることです。分割は、;
複合コマンドを解析するステップ(2)に基づいています。中かっこ拡張が発生したとき(3)は、複合コマンドを生成するにはすでに遅すぎました。
答え3
最初の行
echo systemctl\ {restart,status}\ sshd\;
トークンを3つに拡張
- エコ
- systemctl restart sshd;
- systemctlステータスsshd;
その後、最後の2つのマーカーをエコエコーするとよさそうです。
同じ2行目
systemctl\ {restart,status}\ sshd\;
トークンを2つに拡張
- systemctl restart sshd;
- systemctlステータスsshd;
systemctl restart sshd;
bashは見つからない実行可能ファイルを見つけようとします。
あなたは暗い面で旅行を始め、eval systemctl\ {restart,status}\ sshd\;
予期しないことに気をつけたいかもしれません。