
このコマンドを変数にリダイレクトしたいと思います。
{
printf 'scan on\n\n'
sleep 10
printf 'quit \n\n'
} | bluetoothctl
私はこれを試みます:
variable=$(printf 'scan on\n\n' sleep 10 printf 'quit \n\n' | bluetoothctl)
echo $variable
ただし、空の出力が表示されます。私もそれを分割しようとしました。
variable=$(printf 'scan on\n\n' | bluetoothctl)
sleep 10
printf 'quit \n\n'| bluetoothctl
echo $variable
しかし今回は
Agent registered
[bluetooth]# quit
stdout
変数を実行したときに最初に印刷されたコマンドの出力をどのようにリダイレクトできますか?
答え1
のみ:
variable=$(
{
printf 'scan on\n\n'
sleep 10
printf 'quit \n\n'
} | bluetoothctl
)
コマンド置換の内部は任意のシェルコード1であり、1行にする必要はありません。
bluetoothctl
ここでは、パイプ全体の出力をキャプチャしようとしています(実際には、他のすべてのコマンドのstdoutがパイプにリダイレクトされるため、これはstdoutの出力になりますbluetoothctl
)。
以下を使用して出力をキャプチャすることもできますbluetoothctl
。
{
printf 'scan on\n\n'
sleep 10
printf 'quit \n\n'
} | variable=$(bluetoothctl)
ただし、でbash
動作するには、最後のパイプラインコンポーネントのオプションを設定する必要がありますlastpipe
(shopt -s lastpipe
非対話型シェルインスタンスのみ)。いいえサブシェルで実行します。
しかし、ここではパイプは必要ありません。次のようにできます。
variable=$(bluetoothctl --timeout 10 scan on)
変数の内容を表示するには、次の構文を覚えておいてください。
printf '%s\n' "$variable"
いいえ。echo $variable
詳細については、次を参照してください。
ここの出力には、bluetoothctl
カラー表示エスケープシーケンスと行の内容を消去するために使用されるエスケープシーケンスが含まれています。引用符なしで置くと、$variable
その内容が分割+グローブされ、渡されるランダムな単語のリストが生成され、スペースで区切られて出力されますecho
。echo
したがって、最後の単語が次に終わると、すべての内容が1行に書き込まれます。明確な線シーケンス(私のテストで行ったこと\r\e[K
:キャリッジリターン次は生産ラインの最後までクリアシーケンス)、空行のみが表示されます。
1一部のシェルは、bash
一致しない括弧付きのコードをブロックするために使用されます(たとえば、コードにケースステートメントまたはアンバランスコメントがcase $x in foo)
含まれている場合)
)、シェルパーサはこれを)
コマンド置換を閉じると間違えます。
答え2
エラーはセミコロンがありません(そうでなければ改行文字と同じです)。出力構造を表示するには二重引用符を追加してください。努力する:
variable=$( { printf 'scan on\n\n' ; sleep 10 ; printf 'quit \n\n' ; } | bluetoothctl)
echo "$variable"
答え3
考えられる代替手段は単純なexpect
スクリプトです。
#!/usr/bin/expect
spawn bluetoothctl
send "scan on\r"
sleep 10
send "quit \r"
expect eof
\r
「Return/Enter キーを押す」と同じです。実行ファイルを作成して実行してみてください。