タグ付けされた質問 「command-substitution」

シェルコマンド置換($(command)または `command`など)、そのメカニズム、正しい構文などに関する質問。エイリアスと混同しないでください。

5
生成されたファイル名のリストを引数リストとして使用—スペースあり
によって収集されfindたファイル名のリストを使用してスクリプトを起動しようとしています。特別なものはなく、次のようになります。 $ myscript `find . -name something.txt` 問題は、パス名の一部にスペースが含まれているため、引数の展開時に2つの無効な名前に分割されることです。通常、名前を引用符で囲みますが、ここでは逆引用符の展開によって挿入されます。find各ファイル名の出力をフィルタリングして引用符で囲みましたが、bashがそれらを見るまでにそれらを取り除くには遅すぎて、ファイル名の一部として扱われます: $ myscript `find . -name something.txt | sed 's/.*/"&"/'` No such file or directory: '"./somedir/something.txt"' はい、それがコマンドラインの処理方法のルールですが、どうすれば回避できますか? これは恥ずかしいことですが、私は正しいアプローチを思い付くことに失敗しています。私は最終的にそれをどのように行うかを見つけましたxargs -0 -n 10000...しかし、それは私がまだ聞きたいと思うようなsuchいハックです:バッククォート展開の結果を引用する方法、または別の方法で同じ効果を達成するにはどうすればよいですか? 編集:私は、事実について混乱していたxargs んそれはそう言われていますか、システムの制限を超えることがありますしない限り、単一の引数リストにコレクトすべての引数を。まっすぐに設定してくれてありがとう!他の人は、受け入れられた答えを読んでいるときにこれを覚えておいてください。なぜなら、それは直接指摘されていないからです。 私は答えを受け入れましたが、私の質問は残ります:バックティック(または$(...))拡張でスペースを保護する方法はありませんか?(受け入れられた解決策は非bash回答であることに注意してください)。

7
echoとcatの実行時間にこのような違いがあるのはなぜですか?
回答この質問は、私は別の質問をさせて: 私は、次のスクリプトは、同じことを行う2つ目は、最初のものを使用しているため、はるかに高速であるべきと思ったcat何度もファイルを開く必要がなく、二つだけのファイルを開きます一度だけ変数をエコーし​​ます: (正しいコードについては、更新セクションを参照してください。) 最初: #!/bin/sh for j in seq 10; do cat input done >> output 第二: #!/bin/sh i=`cat input` for j in seq 10; do echo $i done >> output 入力は約50メガバイトです。 しかし、2番目の方法を試したときは、変数のエコーiが大規模なプロセスだったため、遅すぎました。また、2番目のスクリプトで問題が発生しました。たとえば、出力ファイルのサイズが予想よりも小さかったです。 私はまたのmanページを確認echoし、catそれらを比較します: echo-テキストの行を表示します cat-ファイルを連結し、標準出力に出力します しかし、違いはありませんでした。 そう: なぜ2番目のスクリプトでcatがとても速く、エコーがとても遅いのですか? それとも変数の問題ですiか?(そのマニュアルページで echoは「テキスト行」と表示されると言われているので、i。のような非常に長い変数ではなく、短い変数に対してのみ最適化されていると思います。しかし、それは単なる推測です。) そして、使用するときに問題が発生したのはなぜechoですか? 更新 間違って使用するseq 10代わりに使用しました`seq 10`。これは編集されたコードです: 最初: #!/bin/sh for j …

2
コマンド置換から末尾の改行文字はどこに行ったのですか?
次のコードは、状況を最もよく説明しています。最後の行が末尾の改行文字を出力しないのはなぜですか?各行の出力はコメントに表示されます。GNU bashバージョン4.1.5を使用しています echo -n $'a\nb\n' | xxd -p # 610a620a x=$'a\nb\n' ; echo -n "$x" | xxd -p # 610a620a echo -ne "a\nb\n" | xxd -p # 610a620a x="$(echo -ne "a\nb\n")" ; echo -n "$x" | xxd -p # 610a62

3
「-o errtrace」を使用したコマンド置換でのエラーのトラップ(つまり、-Eを設定)
この参照マニュアルによると: -E(-o errtraceも) 設定すると、ERRのトラップは、シェル関数、コマンド置換、およびサブシェル環境で実行されるコマンドに継承されます。このような場合、ERRトラップは通常継承されません。 ただし、以下が機能しないため、間違って解釈する必要があります。 #!/usr/bin/env bash # -*- bash -*- set -e -o pipefail -o errtrace -o functrace function boom { echo "err status: $?" exit $? } trap boom ERR echo $( made up name ) echo " ! should not be reached ! " 私はすでに簡単な割り当てを知っていmy_var=$(made_up_name)ます、でスクリプトを終了しますset -eます。で(つまり、errexit)。 され …

5
リストからgrepファイル
数百のファイルのリストに対してgrepを実行しようとしています。 $ head -n 3 <(cat files.txt) admin.php ajax/accept.php ajax/add_note.php ただし、ファイル内で見つかったことがわかっている文字列を探していても、次のコマンドはファイルを検索しません。 $ grep -i 'foo' <(cat files.txt) $ grep -i 'foo' admin.php The foo was found ファイルからパターン-fを読み取るフラグに精通しています。しかし、入力ファイルの読み方は? 私は、ファイルを一時ディレクトリにコピーするという恐ろしい回避策を考えていたのでcp、<(cat files.txt)フォーマットをサポートしているようで、そこからファイルをgrepします。シャーリーにはもっと良い方法があります。

2
サブシェル内のネストされた引用符
次のようなサブシェル出力をカプセル化するには、引用符を使用する必要があるとします。 DATA="$(cat file.hex | xxd -r)" しかし、次のようなものをネストする必要があります。 DATA="$(cat file.hex | xxd -r | tr -d \"$(cat trim.txt)\")" 単一引用符は、その中にある変数を展開しないため、使用できません。引用符のエスケープは、受動的なテキストとして扱われるため機能しません。 これをどのように処理しますか?

1
ksh93はコマンド置換でフォークをどのように回避しますか
与えられた cmd='fun(){ echo "$@"; }; fun $(fun $(fun hi))' シェルはそれを実現するために2つのフォークを作る必要がある傾向があります strace-f(){ strace -f "$@" 2>&1; }; for sh in dash bash zsh ksh; do printf "$sh\t" ; strace-f $sh -c "$cmd" |grep -e clone -e fork -c; done ksh一度もフォークせずに英雄的に作成する場合を除きます: dash 2 bash 2 zsh 2 ksh 0 それはどうやって? 編集: パイプがスローされると、次のようになります。 …

3
多変数forループ
forループ内に複数の変数(整数だけでなく)を指定する方法はありますbashか?作業する必要がある任意のテキストを含む2つのファイルがある場合があります。 機能的に必要なのは次のようなものです: for i in $(cat file1) and j in $(cat file2); do command $i $j; done 何か案は?

3
コマンド置換を介して別のコマンドの引数を生成するにはどうすればよいですか
次から: シェルコマンド置換での予期しない動作 私は引数の膨大なリストを取ることができるコマンドを持っています、それらのいくつかは合法的にスペースを含むことができます(そしておそらく他のもの) これらの引数を引用符で生成できるスクリプトを書きましたが、出力をコピーして貼り付ける必要があります。 ./somecommand <output on stdout with quoting> ./othercommand some_args <output from above> 私は単にすることでこれを合理化しようとしました ./othercommand $(./somecommand) そして、上記の問題で言及された予期しない動作に遭遇しました。問題はothercommand、いくつかの引数が引用符を必要とし、これを変更できないことを前提として、コマンド置換を使用して引数を確実に生成できるかどうかです。

4
Bashのファイル読み取りコマンド置換を理解する
私はBashが次の行をどのように扱うかを理解しようとしています: $(< "$FILE") Bashのmanページによると、これは次と同等です。 $(cat "$FILE") この2行目の推論の行を追うことができます。Bashはで変数展開を実行し$FILE、コマンド置換を入力し、$FILEto の値を渡しcat、catはの内容$FILEを標準出力に出力します。コマンド置換は、行全体を内部のコマンドの結果である標準出力で置き換えることで終了し、Bashはそれを実行しようとします簡単なコマンド。 ただし、上記の1行目は$FILE、Bashが$FILEで変数置換を実行し、Bashが標準入力を読み取るために開き、標準入力が標準出力にコピーされ、コマンド置換が終了し、結果の標準をBashが実行しようとすることを理解しています。出力。 誰かが私に$FILEstdinからstdoutへのコンテンツの流れを説明してくれませんか

2
割り当ては、コマンド置換がある場合を除いて、終了ステータスを持つコマンドに似ていますか?
次の例とそれらのPOSIXシェルでの出力を参照してください。 false;echo $?またはfalse || echo 1:1 false;foo="bar";echo $?またはfoo="bar" && echo 0:0 foo=$(false);echo $?またはfoo=$(false) || echo 1:1 foo=$(true);echo $?またはfoo=$(true) && echo 0:0 /programming/6834487/what-is-the-variable-in-shell-scriptingの最高投票の回答で述べたように: $? 最後に実行されたコマンドの戻り値を見つけるために使用されます。 これはおそらくこの場合少し誤解を招く可能性があるので、そのスレッドからの投稿でも引用されているPOSIX定義を取得しましょう。 ?最新のパイプラインの10進数の終了ステータスに展開します(パイプラインを参照)。 したがって、割り当て自体はゼロの終了値を持つコマンド(またはパイプラインパーツ)としてカウントされているように見えますが、割り当ての右側の前に適用されます(たとえば、ここでの例ではコマンド置換呼び出し)。 この振る舞いが実用的な見地からどのように意味を成すかはわかりますが、割り当て自体がその順序でカウントされることは、私には幾分珍しいようです。多分それが私にとって奇妙な理由をより明確にするために、割り当てが関数であったと仮定しましょう: ASSIGNMENT( VARIABLE, VALUE ) そしてfoo="bar"だろう ASSIGNMENT( "foo", "bar" ) のfoo=$(false)ようなものになります ASSIGNMENT( "foo", EXECUTE( "false" ) ) そのことを意味するEXECUTE実行が最初と後にのみ ASSIGNMENT実行されますが、それはまだだEXECUTEここで問題のステータス。 私の評価は正しいですか、それとも何かを誤解/不足していますか?これらは、私がこの振る舞いを「奇妙な」ものと見なす正しい理由ですか?

2
変数割り当ての戻りステータスはどのように決定されますか?
私はこのようなスクリプトの構成を見てきました: if somevar="$(somecommand 2>/dev/null)"; then ... fi これはどこかに文書化されていますか?変数の戻りステータスはどのように決定され、コマンド置換とどのように関連していますか?(たとえば、私は同じ結果を得るでしょうif echo "$(somecommand 2>/dev/null)"; thenか?)

3
コマンド置換を変数置換にネストできますか?
コマンドを介してアクセスする特定の文字列に変数置換を使用したいと思います。たとえば、クリップボードに何かをコピーすると、次のようにアクセスできます。 $ xclip -o -selection clipboard Here's a string I just copied. これを変数に割り当てると、変数の置換を行うことができます。 $ var=$(xclip -o -selection clipboard) $ echo $var Here's a string I just copied. $ echo ${var/copi/knott} Here's a string I just knotted. しかし、変数に代入せずに変数置換を行う方法はありますか?概念的には、このようなものです。 $ echo ${$(xclip -o -selection clipboard)/copi/knott} bash: ${$(xclip -o -selection clipboard)/copi/knott}: bad substitution …

1
サブシェルを引用し、結果をエコーに渡す最後に改行がないのはなぜですか?
ls | grep pnggrepの出力を行うと、次のようになります。 2015-05-15-200203_1920x1080_scrot.png 2015-05-16-025536_1920x1080_scrot.png (ファイル名、改行、ファイル名、改行) 次に、echo $(ls | grep png)出力: 2015-05-15-200203_1920x1080_scrot.png 2015-05-16-025536_1920x1080_scrot.png (ファイル名、単語分割からのスペース、ファイル名、改行!!エコーから!!) これで問題ありませんが、単語の分割を防ぐためにこれを行うecho "$(ls | grep png)"と、出力は次のようになります。 2015-05-15-200203_1920x1080_scrot.png 2015-05-16-025536_1920x1080_scrot.png そして私の質問は、2番目の改行はどこにあるのか(1つはgrepから、もう1つはechoから)ですか?

2
find -execのifコマンド
私は現在のディレクトリの下にあるすべてのディレクトリとファイルを一覧表示し、それらがファイルまたはディレクトリである場合は、次のコマンドで書き込もうとしました: find -exec echo `echo {} : ;if [ -f {} ]; then echo file; else echo directory;fi` \; 私はそれがばかげたコマンドであることを知っています、-type fまたはのような他のものを使用できます-type dが、そのコードの一部が期待どおりに機能しなかった理由を知りたいです。それらすべてにディレクトリを出力するだけです。たとえば、出力findは次のとおりです。 . ./dir ./dir/file 私のコードの出力は: . : directory ./dir : directory ./dir/file : directory そしての出力 echo `echo dir/file : ;if [ -f dir/file ]; then echo file; else echo …

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.