
では、bash
コマンドを実行する前に、括弧拡張がシェル操作として実行されます。1これは、以下が機能することを意味します。
echo {1..10} >output | at -m now
出力は次のとおりです1 2 3 4 5 6 7 8 9 10
。
うまくいかないのは、コマンドがat
実行されることを警告するコマンドで中括弧を拡張しようとすることです/bin/sh
。私の場合、中dash
かっこを使用した範囲拡張へのリンクはサポートされていないようです。
$ at - now
warning: commands will be executed using /bin/sh
at> echo {1..10} >output
at> <EOT>
dash
その後(またはBourneまたは接続しているすべてのシェル)でコマンドが実行され、/bin/sh
出力が生成されます{1..10}
。
このようにコマンドを使用するときに中かっこを拡張するにはどうすればよいですかat
?
プロンプトでコマンドを実行できるように、回答として投稿した以外に他の解決策を見たいと思いますbash
。at
プロンプトで実行されるすべての単一行コマンド用のスクリプトを作成することは、必要以上の努力のようですat
。
答え1
3つの簡単な異なるオプションがあります。 1つはわずかに脆弱で、シェルの実装の詳細に依存し、もう1つは使用します。ここにファイルbash
インラインスクリプトと-c
1行配信用の別のスクリプトを提供してください。
最も信頼性が高くポータブルな方法はここのドキュメント:
$ at now
warning: commands will be executed using /bin/sh
at> bash <<'EOF'
at> echo {1..5} >/tmp/output
at> EOF
at> <EOT>
job 24 at Mon Mar 23 20:41:20 2015
$ cat /tmp/output
1 2 3 4 5
<<word
標準入力として提供されるbash
まで続くhere文書を宣言しますword
。ファイルを引用すると'EOF'
シェル拡張は適用されないので、食べなくても$
本文に書き込むことができます。dash
スクリプトEOF
には、行の先頭に(または選択した単語)を除くすべての項目を含めることができます。
これが私が推奨するアプローチです。bash
ほとんど使ったように書くことができます。最初と最後に1行だけ追加すると、何が起こっているのかを確認できます。
本当に一行なら使用bash -c
単一のコマンドを渡して実行します。
$ at now
warning: commands will be executed using /bin/sh
at> bash -c 'echo {1..3} >/tmp/output'
at> <EOT>
job 25 at Mon Mar 23 20:50:03 2015
$ cat /tmp/output
1 2 3
コマンドに引用符を使用すると、少し問題が発生する可能性があります。
最も要求の厳しいのは、通常、タスクatd
が標準入力としてシェルに送信されることです(ただし、これが必要だとは思わない)。シェルは通常、標準入力を1行ずつ読みます(ただし、この方法で実行する必要はありません)。
実際にこれが実装されている場合は、他のシェルでタスクを実行する不快なトリックを実行できます。
$ at now
warning: commands will be executed using /bin/sh
at> bash
at> echo {1..10} >/tmp/output
at> <EOT>
job 22 at Mon Mar 23 20:40:00 2015
$ cat /tmp/output
1 2 3 4 5 6 7 8 9 10
sh
これは、最初の行を読み取って実行してbash
からbash
、標準入力の残りの部分をコマンドで読み取るために機能します。これは非常に脆弱ですが、動作するときに最も侵害性の低いバージョンです。
dash
この点で、それ自体は多くのシェルよりも複雑であり、内部バッファを埋めることがより重要です。 BusyBox などの他の単純なシェルにはsh
ラインバッファリング動作があることがよくあります。
最後に、あなたは決して必須別のスクリプトファイルを使用すると、多くの場合、実際には巧妙にするよりも優れたオプションになります。タスクがワンタイムであるかプログラムで作成される場合はすべて合理的な選択肢ですが、他の場合はメンテナンスの観点からスタンドアロンスクリプトを使用することが価値があるかもしれません。
私は最後のオプションでstdinを使用することを本当にお勧めしませんが、それはかわいいトリックです。
答え2
bash
これまでに私が見つけた唯一の解決策は、インタプリタの使用を指定するスクリプト(expandme.shと呼びます)を作成することです。
#!/bin/bash
echo {1..10} >output
その後、プロンプトでスクリプトを実行しますat
。
$ at - now
warning: commands will be executed using /bin/sh
at> expandme.sh
at> <EOT>
今スクリプトは、出力をダンプする前に私たちをdash
/Bourne
追放から取り出し、拡張を実行します。