
さまざまなシンボルを使用してさまざまなコマンドをリンクするオンラインチュートリアルを頻繁に表示します。たとえば、
command1 | command2
command1 & command2
command1 || command2
command1 && command2
他の人はコマンドをファイルにリンクするようです。
command1 > file1
command1 >> file1
これらは何ですか?名前は何ですか?彼らは何をしていますか?もっとありますか?
答え1
これをシェル演算子といい、その他にもあります。 2つの主要カテゴリのうち最も一般的なカテゴリを簡単に説明します。制御演算子そしてリダイレクト演算子、とbashシェルで動作する方法。
A. 制御演算子
シェルコマンド言語で制御機能を実行するタグ。
次の記号のいずれかです。
& && ( ) ; ;; <newline> | ||
バッシュから|&
。
A!
はいいえ制御演算子ですが、予約語。論理NOT [否定演算子]になります。算術表現内部テスト構造(まだ空白の区切り文字が必要です)。
A.1 リスト終了者
;
: 最初のコマンドの結果に関係なく、他のコマンドが完了した後に 1 つのコマンドを実行します。command1 ; command2
まずcommand1
、前景で実行し、完了するとcommand2
実行されます。
文字列リテラルにないか、特定のキーワードの後に改行がありません。いいえセミコロン演算子と同じです。単純なコマンドの区切りリスト;
はまだあります。リスト- シェルのパーサーと同様に、別の単純な;
コマンドに従う単純なコマンドは実行前に読み取る必要があり、改行はコマンドのリスト全体またはリストのリストを区別できます。違いは微妙ですが複雑です。改行は、シェルが改行後のデータを読み取る前のコマンドがないと仮定し、シェルが読み取った単純なコマンドの評価を開始できる点を示しますが、セミコロンはそうではありません;
。
&
:バックグラウンドでコマンドが実行されるため、同じシェルで作業を続けることができます。command1 & command2
ここではcommand1
バックグラウンドで起動し、終了をcommand2
待たずに直ちにフォアグラウンドで実行を開始しますcommand1
。
次の改行文字はcommand1
オプションです。
A.2 論理演算子
&&
:他のコマンドが正常に終了した場合にのみ、1つのコマンドを実行できるANDのリストを作成するために使用されます。command1 && command2
完了するとここで実行されますcommand2
。command1
ただ成功した場合command1
(終了コードが0の場合)、両方のコマンドはフォアグラウンドで実行されます。
このコマンドは次のように書くこともできます。
if command1
then command2
else false
fi
またはif command1; then command2; fi
返品ステータスを無視してください。
||
:他のコマンドが終了しない場合にのみ、1つのコマンドを実行できるORリストを作成するために使用されます。command1 || command2
ここでは、command2
失敗時にのみ実行されますcommand1
(ゼロ以外の終了ステータスが返される場合)。どちらのコマンドもフォアグラウンドで実行されます。
このコマンドは次のように書くこともできます。
if command1
then true
else command2
fi
またはより短い方法でif ! command1; then command2; fi
。
&&
とは||
関連付けられていることに注意してください。シェル論理演算子&&および||の優先順位より多くの情報を知りたいです。
!
:これは "not"演算子として機能する予約語です(ただし、区切り文字が必要です)。コマンドの戻り状態を否定するために使用されます。コマンドがゼロ以外の状態を返す場合は、ゼロを返します。状態0の場合は1を返します。プログラムロジックNOT 1を返すことも実用的ですtest
。! command1 [ ! a = a ]
算術式の実際のNOT演算子:
$ echo $((!0)) $((!23))
1 0
A.3 パイプラインオペレータ
|
: あるコマンドの出力を別のコマンドの入力に渡すパイプ演算子です。パイプ演算子で作成されたコマンドが呼び出されます。管路。command1 | command2
印刷されたすべての出力
command1
はに入力として渡されますcommand2
。|&
2>&1 |
:これはbashとzshの略です。あるコマンドの標準出力と標準エラーを別のコマンドの入力に渡します。command1 |& command2
A.4その他のリスト句読点
;;
終了を表示するためにのみ使用されます。ケースステートメント。 Ksh、bash、zshは;&
次のケースにジャンプし;;&
(ATT kshではない)、後続のケースをテストし続ける機能もサポートします。
(
そして)
慣れてください。グループコマンドサブシェルから始めます。{
および}
グループコマンドを使用しますが、サブシェルで実行しないでください。バラよりこの回答シェル構文のさまざまな種類の括弧、角括弧、および中括弧について話し合います。
B. リダイレクト演算子
シェルコマンド言語でリダイレクト機能を実行するトークンです。次の記号のいずれかです。
< > >| << >> <& >& <<- <>
これにより、コマンドの入力と出力を制御できます。単純なコマンド内でもコマンドの後にも表示できます。リダイレクトは、表示された順序で左から右に処理されます。
<
:コマンドを入力します。command < file.txt
上記の内容はのcommand
内容に従って実行されますfile.txt
。
<>
:上記と同じですが、ファイルは次の場所で開きます。読み取り+書き込み代わりにパターン読み取り専用:command <> file.txt
ファイルが存在しない場合は生成されます。
この演算子はほとんど使用されません。なぜなら、コマンドは通常読むしかし、標準入力ではさまざまな特定の状況で役に立ちます。。
>
:コマンドの出力をファイルに送信します。command > out.txt
上記は出力をcommand
。out.txt
ファイルが存在する場合はその内容が上書きされ、ファイルが存在しない場合はファイルが生成されます。
この演算子はまた、何かを印刷するかどうかを選択するためによく使用されます。標準エラーまたは標準出力:
command >out.txt 2>error.txt
上記の例では、>
標準出力がリダイレクトされ、2>
標準エラーがリダイレクトされます。リダイレクトされた出力を使用することも可能です1>
が、これがデフォルト値なので、1
一般的に省略して単純に>
。
したがって、これを実行しcommand
、エラーメッセージと共にfile.txt
出力を保存するには、次の手順を実行します。out.txt
error.txt
command < file.txt > out.txt 2> error.txt
>|
::と同じですが、シェルが>
上書きを拒否するように設定されていても(set -C
または使用set -o noclobber
)ターゲットを上書きします。command >| out.txt
存在する場合out.txt
の出力はcommand
その内容を置き換えます。存在しない場合に生成されます。
>>
:と同じです>
が、ターゲットファイルが存在する場合は新しいデータが追加されます。command >> out.txt
out.txt
存在する場合は、command
すでに存在する項目に出力を追加します。存在しない場合に生成されます。
>&
:(POSIX仕様に従って)次に囲まれた場合数字(1>&2
)または-
右(1>&-
)リダイレクトのみ可能一つファイル記述子を削除または閉じます(>&-
)。
>&
ファイル記述子番号の後に続くのは、ファイル記述子をリダイレクトする移植可能な方法であり、ファイル>&-
記述子を閉じる移植可能な方法です。
このリダイレクトの右側がファイルの場合は、次のトピックをお読みください。
>&
、&>
および:(上記>>&
参照&>>
)標準エラーと標準出力をそれぞれ置換または追加してリダイレクトします。command &> out.txt
標準エラーと標準出力は両方command
に保存され、out.txt
内容を上書きするか、内容がない場合は新しく作成されます。
command &>> out.txt
上記と同じです。ただしout.txt
、存在する場合の出力とエラーがcommand
追加されます。
この&>
亜種はbash
csh >&
(数十年前)に由来しています。これらはすべて他のPOSIXシェル演算子と競合するため、移植可能なスクリプトには使用しないでくださいsh
。
<<
:ここに文書があります。通常、複数行の文字列を印刷するために使用されます。command << WORD Text WORD
ここでは、上記の例で次の項目が見つかるまですべてが入力として使用され
command
ます。通常、またはそのバリアントですが、目的の英数字(単なる)文字列にすることができます。の一部が引用またはエスケープされると、ここの文書のテキストは文字通り処理され、拡張(変数など)は行われません。引用符なしで置くと、変数が拡張されます。詳細については、次を参照してください。WORD
Text
WORD
EoF
WORD
バッシュマニュアル。command << WORD ... WORD
出力を別のコマンドに直接パイプするには、パイプを<< WORD
終了するWORDの後ろまたは後ろの行ではなく、同じ行に配置する必要があります。たとえば、command << WORD | command2 | command3... Text WORD
<<<
:ここの文字列はここのドキュメントに似ていますが、1行です。これは、Unixポートまたはrc(元の場所)、zsh、ksh、yash、およびbashの特定の実装にのみ存在します。command <<< WORD
与えられたすべてはWORD
拡張され、その値はに入力として渡されますcommand
。これは通常、変数の内容をコマンドに入力として渡すために使用されます。たとえば、
$ foo="bar"
$ sed 's/a/A/' <<< "$foo"
bAr
# as a short-cut for the standard:
$ printf '%s\n' "$foo" | sed 's/a/A/'
bAr
# or
sed 's/a/A/' << EOF
$foo
EOF
他の演算子(>&-
、、x>&y
x<&y
)を使用してファイル記述子を閉じたりコピーしたりできます。これについての詳細は、シェルマニュアルの関連セクション(ここ例:バッシュ)。
ここでは、Bourneに似たシェルの最も一般的な演算子のみを扱います。一部のシェルには独自の追加リダイレクト演算子があります。
Ksh、bashおよびzshにも<(…)
、>(…)
および構造があります=(…)
(後者のみzsh
)。これはリダイレクトではありません。プロセスの交換。
答え2
「>」に関する警告
I / Oリダイレクト(<
および>
注文する…入力ファイル>同じファイル
または
注文する… <文書 >同じファイル
またはほぼ同等に、
猫文書|注文する… >同じファイル
(grep
、、、およびはsed
、人々がこれらの構造で使用しようとするコマンドの例です。)ユーザーは、この状況によってファイルが空になる可能性があることに驚きました。cut
sort
spell
他の答えでは言及されていない微妙な違いは、最初の文で見つけることができますリダイレクト部分大きな打撃(1):
コマンドが実行される前に、コマンドの入力と出力が変更されることがあります。リダイレクト シェルで解釈される特殊記号を使用します。
最初の5つの単語は、太字、イタリック体、アンダースコア、ズームイン、点滅、赤色でなければならず、アイコンでマークされ、シェルがリクエストリダイレクトを実行することを強調する必要があります。
コマンド実行前。また覚えておいてください
出力リダイレクトのためにファイルが書き込み用に開かれます。
したがって、この例では次のようになります。
sort roster > roster
シェルは書き込み用にファイルを開き、
roster
プログラムの実行が開始される前にファイルを切り取ります(つまり、すべての内容を削除します)。sort
もちろん、データを回復するために何もできません。素朴に期待できる
tr "[:upper:]" "[:lower:]" < poem > poem
より良いかもしれません。シェルは左から右方向のリダイレクトを処理するため、書き込み(標準出力)のために開く前に
poem
読み取り(tr
標準入力)のために開きます。しかし、これは役に立ちません。この一連の操作では、2つのファイルハンドルが作成されますが、両方とも同じファイルを指します。シェルが読み取り用にファイルを開くと、内容はそのまま残りますが、プログラムが実行される前にまだ破損しています。
それではどうすればいいですか?
ソリューションには以下が含まれます。
実行中のプログラムに出力位置を指定する独自の内部機能があることを確認してください。これは通常
-o
(または)マークとして表示されます--output=
。特に、sort -o roster roster
ほぼ等しい
sort roster > roster
最初の場合を除いて、
sort
プログラムは出力ファイルを開きます。それまでは十分スマートです。後ろにすべての入力ファイルを読みました。同様に、少なくとも一部のバージョン
sed
では-i
(編集私n位置)オプションは、出力を入力ファイルに書き換えるために使用できます(同様に、後ろにすべての入力を読みました。)ed
/ex
、、emacs
/pico
などvi
のエディタを使用すると、vim
ユーザーはテキストファイルを編集し、編集したテキストを元のファイルに保存できます。ed
(少なくとも)非対話型で使用できます。vi
関連機能があります。入力すると編集バッファの内容を書き込みます。:%!command
Entercommand
、出力を読み取り、それをバッファに挿入します(元のコンテンツの置き換え)。
シンプルだが効果的:
注文する…入力ファイル>一時ファイル && MV一時ファイル 入力ファイル
これには次の欠点があります。
input_file
リンクなので(おそらく)別のファイルに置き換えられます。また、新しいファイルはあなたの所有となり、デフォルトで保護されています。特に、これにより元のファイルがあっても、ファイルを世界中で読み取ることができるリスクが発生します。input_file
いいえ。多様性:
command … input_file > temp_file && cp temp_file input_file && rm temp_file
これはまだ(おそらく)去るtemp_file
世界は読むことができます。より良い点は次のとおりです。cp input_file temp_file && command … temp_file > input_file && rm temp_file
これにより、ファイルのリンク状態、所有者、およびモード(保護)が維持されますが、I / Oコストが2倍になる可能性があります。 (属性を保存するには、-a
on-p
などのオプションを使用する必要があります。)cp
command … input_file > temp_file &&
cp --attributes-only --preserve=all input_file temp_file &&
mv temp_file input_file
(読みやすくするために別々の行で区切られます)これはファイルのモード(ルートの場合はファイルの所有者)を維持しますが、そのファイルをユーザーのものにし(ルートでない場合)、新しい別々のファイルにします。
このブログ (ファイルの「内部」編集)提案と説明
{RM入力ファイル && 注文する… >入力ファイル; } <入力ファイル
これを行うには
command
標準入力を処理できます(ただし、ほぼすべてのフィルタが処理します)。ブログ自体ではこれを危険なパッチワークと呼び、使用をお勧めしません。これにより、あなたが所有し、基本的な権限を持つ別の新しいファイル(何もリンクされていません)が作成されます。moreutilsパッケージには次のコマンドがあります
sponge
。注文する…入力ファイル|スポンジ同じファイル
バラよりこの回答より多くの情報を知りたいです。
私を完全に驚かせたのは次のとおりです。 文法エラーが言う:
[これらのソリューションのほとんどは]読み取り専用ファイルシステムでは失敗します。ここで「読み取り専用」とは
$HOME
〜する書くことができますが/tmp
、読み取り専用(基本的に)。たとえば、Ubuntuがあり、回復コンソールから起動した場合、これは一般的です。また、この文書演算子は必要<<<
に応じて機能しません。/tmp
読み書き 一時ファイルも書き込むからです。
(よりこの問題strace
'd出力を含む)
この場合、次のことが機能します。
- 上級ユーザーのみ:
コマンドが入力と同じ量の出力データを生成することが保証されている場合(たとえば
sort
、tr
いいえ-d
またはオプション-s
)試してみることができます。注文する…入力ファイルdd =同じファイル変換=notrunc
バラよりこの回答 そしてこの回答上記の説明と、コマンドが入力と同じ量の出力データを生成することを保証する可能性のある代替案を含む、詳細をご覧ください。以下(例:grep
、またはcut
)。これらの答えの利点は、空きスペースが必要ないことです(またはスペースがほとんど必要ありません)。上記の表に対する答えは、システムに入力(既存)ファイル全体と出力(新しい)ファイルの両方を収容するのに十分な空き容量が必要であることを明示的に要求します。これは他のほとんどのソリューション(例:と)です。例外:出力を書き込む前にすべての入力を読み取る必要があり、一時ファイルの大部分(すべてではありません)のデータをバッファリングできるため、多くの空き容量が必要になる場合があります。command … input_file > temp_file && …
sed -i
sponge
sort … | dd …
sort
- 上級ユーザーのみ:
注文する…入力ファイル1<>同じファイル
dd
おそらく上記の答えと同じでしょう。この構文は、ファイル記述子で指定されたファイルを開きます。n<> file
n
入出力用 、切らず - 一種の and の組み合わせと同じです。注:一部のプログラム(例:および)は、入力と出力が同じファイルであることを検出できるため、この場合は実行を拒否することがあります。バラよりn<
n>
cat
grep
この回答 上記の議論とコマンドが入力と同じ量の出力データを生成することが保証されている場合、この回答が機能するようにするスクリプト以下。
警告:Peterのスクリプトをテストしていないため保証できません。
それでは、問題は何ですか?
これはU&Lの人気トピックで、次の質問で解決されます。
- ファイルを適切に変更する方法はありますか?
iconv
入力ファイルを変換された出力に置き換える方法は?- このコマンドが
shuf file > file
空のファイルを残すのはなぜですか? - 上書きせずにLinuxで同じファイルを読み書きできますか?
- 命令で処理されたソースファイルと同じファイルにリダイレクト
- この
sort
コマンドが空のファイルを提供するのはなぜですか? tr
標準出力をファイルにリダイレクトする- grep:入力ファイル「X」も出力されます。
- リダイレクト演算子はファイル記述子を並列に開くことができますか?
- リダイレクトはファイルを上書きせずに空のファイルのみを生成します。
...スーパーユーザーやAsk Ubuntuは含まれません。上記の質問に対する回答の多くの情報をこの回答に含めましたが、すべてではありません。 (つまり、詳細については上記の質問と回答を読んでください。)
PS:私いいえ上記のブログにリンクされています。
答え3
;
&
, ,(
と の追加観測)
terdonの回答の一部のコマンドは空白になることがあります。たとえば、次のように言うことができます。
command1 ;
(いいえ
command2
)。これは次のとおりです。command1
(つまり、
command1
前景で実行され、完了するのを待ちます。対照的に、command1 &
(None) は
command2
バックグラウンドで起動し、すぐに別のシェルプロンプトを発行します。command1
一方、、、、は
command1 &&
意味がありません。これらのいずれかを入力すると、シェルはコマンドが別の行に続くと想定します。通常、に設定されているセカンダリ(続き)シェルプロンプトが表示され、読み続けます。シェルスクリプトでは、次の行を読み、読み取った内容に追加します。 (注:これはあなたが望むものではないかもしれません。)command1 ||
command1 |
>
注:一部のシェルの一部のバージョンでは、これらの不完全なコマンドをエラーとして扱うことがあります。この場合(または実際にどの
\
コマンドが非常に長い場合は、行の末尾にバックスラッシュ()を追加して、シェルに別の行からコマンドを読み続けるように指示できます。command1 && \ command2
または
find starting-directory -mindepth 3 -maxdepth 5 -iname "*.some_extension" -type f \ -newer some_existing_file -user fred -readable -print
terdonが言ったように、
(
コマンド)
をグループ化するために使用できます。この議論と「関連性が少ない」という主張は議論の余地があります。 terdonの答えに出てくるコマンドのいくつかはコマンドかもしれません。グループ。例えば、( command1 ; command2 ) && ( command3; command4 )
これを行う:
- 実行し
command1
て完了するまで待ちます。 - 次に、最初のコマンド実行結果が何でも実行され、
command2
完了するまで待ちます。 だから
command2
成功すれば、- 実行し
command3
て完了するまで待ちます。 - その後、結果に関係なくコマンドを実行し、
command4
完了するまで待ちます。
失敗した場合は、
command2
コマンドラインの処理を停止します。- 実行し
- 実行し
括弧の外では、
|
組み合わせは非常にタイトです。command1 | command2 || command3
等しい
( command1 | command2 ) || command3
そして
&&
より||
密接に結ばれて;
いるのでcommand1 && command2 ; command3
等しい
( command1 && command2 ) ; command3
つまり、および
command3
/または終了状態に関係なく実行されます。command1
command2