LoginSignup
20

More than 5 years have passed since last update.

Linuxコマンドの連結の挙動

Last updated at Posted at 2018-05-23

手順書とか作っててLinux系のコマンドとか複数行に分けて書くのが面倒だったので、一行で書きたい!
→ コマンドを&でつないだけどどうやら実行結果が思い通りに行かないので備忘録的にLinuxコマンドの連結の挙動をまとめる

事前準備

  1. 異常終了を返すシェルを用意する

    false.sh
    #!/bin/bash/
    #実行されたことがわかるように文字列出力
    echo "this shellscript is return false"
    #異常終了のステータス値
    exit 1
    
  2. 正常終了を返すシェルを用意する

    true.sh
    #!/bin/bash/
    #実行されたことがわかるように文字列出力
    echo "this shellscript is return true"
    #正常終了のステータス
    exit 0
    

Linuxコマンドの連結の種類

1. ;
2. &$
3. &
4. |
5. ||

検証

;(セミコロン)

  • 実行結果に関わらずとにかく書いたコマンドを次々に実行しまくる
$ bash false.sh ; echo congraturation!!!
this shellscript is return false
congraturationbash!

異常終了を表す1を返すbashファイルを実行しても後続のechoも実行される

もちろんどんなに繋げても

$ bash false.sh ; bash false.sh ; bash false.sh ; bash false.sh ; bash false.sh ; bash false.sh ; bash false.sh ; bash false.sh ; echo congraturation!
this shellscript is return false
this shellscript is return false
this shellscript is return false
this shellscript is return false
this shellscript is return false
this shellscript is return false
this shellscript is return false
this shellscript is return false
congraturation!

&&(アンド×2)

先ほどとは打って変わってこちらは正常終了したら後続のコマンドを実行するので、実行結果が異常終了した時点で実行が止まります

$ bash false.sh  && echo congraturation!
this shellscript is return false

もちろんechoは実行されない

$ bash true.sh && bash false.sh && echo congraturation!
this shellscript is return true
this shellscript is return false

最後のechoまでは到達しない

&(アンド)

&&と混同しないように!
&だけでは同時(並列)実行になってしまうので、例えば下記のように

  1. hogeディレクトリを作成
  2. hogeディレクトリに移動
  3. gitのリポジトリをclone

見たいなことがしたいときに↓のようにしてしまうと普通にカレントディレクトリにリポジトリをcloneされるっということが起きかねません!

$ mkdir hoge/ & cd hoge/ & git clone {ripository}

ということで本当に並列で実行されているのか確認するために下記のようなシェルを用意してください。

hoge.sh
#!/bin/bash/

for i in 1 2 3 4 5 6 7 8 9
do 
    echo I\'m hoge! current roop is $i time .
    sleep 1
done
fuga.sh
#!/bin/bash/

for i in 1 2 3 4 5 6 7 8 9
do 
    echo I\'m fuga! current roop is $i time .
    sleep 1
done

並列実行されているなら交互にechoの内容を出力するはず!

$ bash fuga.sh & bash hoge.sh
I'm fuga! current roop is 1 time .
I'm hoge! current roop is 1 time .
I'm fuga! current roop is 2 time .
I'm hoge! current roop is 2 time .
I'm fuga! current roop is 3 time .
I'm hoge! current roop is 3 time .
I'm fuga! current roop is 4 time .
I'm hoge! current roop is 4 time .
I'm fuga! current roop is 5 time .
I'm hoge! current roop is 5 time .
I'm fuga! current roop is 6 time .
I'm hoge! current roop is 6 time .
I'm fuga! current roop is 7 time .
I'm hoge! current roop is 7 time .
I'm hoge! current roop is 8 time .
I'm fuga! current roop is 8 time .
I'm fuga! current roop is 9 time .
I'm hoge! current roop is 9 time .

綺麗に出力されました🎉

||(パイプ×2)

&&とは真逆!
異常終了したら後続のコマンドを実行するので、実行結果が正常終了した時点で実行が止まります。

$ bash true.sh || echo something error!
this shellscript is return true

正常終了するのでechoは実行されない

$ bash false.sh || echo something error!
this shellscript is return false
something error!

異常終了した場合は後続のコマンドが実行される

$ bash false.sh || bash true.sh || echo something error!
this shellscript is return false
this shellscript is return true

最後のechoまでは到達しない

| パイプ

今までのものと比べてちょっと変わっている
前のコマンドの標準出力結果を後続のコマンドに引き渡す!

これは所感ですが基本grepでしか使うことがあんまりなさそう....あとはxargsmoreくらい

一応例としては下記みたいな都道府県名と県庁所在地がペアで羅列されているテキストがある時、この中から東京の情報だけ取得したい!という時にgrepと組み合わせることでそれが実現できます

prefecture.txt
北海道(ほっかいどう) 札幌(さっぽろ)
青森県(あおもり) 青森(あおもり)
岩手県(いわて) 盛岡(もりおか)
宮城県(みやぎ) 仙台(せんだい)
秋田県(あきた) 秋田(あきた)
山形県(やまがた) 山形(やまがた)
福島県(ふくしま) 福島(ふくしま)
茨城県(いばらき) 水戸(みと)
栃木県(とちぎ) 宇都宮(うつのみや)
群馬県(ぐんま) 前橋(まえばし)
埼玉県(さいたま) さいたま
千葉県(ちば) 千葉(ちば)
東京都(とうきょう) 東京(とうきょう)
神奈川県(かながわ) 横浜(よこはま)
新潟県(にいがた) 新潟(にいがた)
富山県(とやま) 富山(とやま)
石川県(いしかわ) 金沢(かなざわ)
福井県(ふくい) 福井(ふくい)
山梨県(やまなし) 甲府(こうふ)
長野県(ながの) 長野(ながの)
岐阜県(ぎふ) 岐阜(ぎふ)
静岡県(しずおか) 静岡(しずおか)
愛知県(あいち) 名古屋(なごや)
三重県(みえ) 津(つ)
滋賀県(しが) 大津(おおつ)
京都府(きょうと) 京都(きょうと)
大阪府(おおさか) 大阪(おおさか)
兵庫県(ひょうご) 神戸(こうべ)
奈良県(なら) 奈良(なら)
和歌山県(わかやま) 和歌山(わかやま)
鳥取県(とっとり) 鳥取(とっとり)
島根県(しまね) 松江(まつえ)
岡山県(おかやま) 岡山(おかやま)
広島県(ひろしま) 広島(ひろしま)
山口県(やまぐち) 山口(やまぐち)
徳島県(とくしま) 徳島(とくしま)
香川県(かがわ) 高松(たかまつ)
愛媛県(えひめ) 松山(まつやま)
高知県(こうち) 高知(こうち)
福岡県(ふくおか) 福岡(ふくおか)
佐賀県(さが) 佐賀(さが)
長崎県(ながさき) 長崎(ながさき)
熊本県(くまもと) 熊本(くまもと)
大分県(おおいた) 大分(おおいた)
宮崎県(みやざき) 宮崎(みやざき)
鹿児島県(かごしま) 鹿児島(かごしま)
沖縄県(おきなわ) 那覇(なは)
  • まずはcatだけの出力
    • ※長いので出力結果割愛しています。
$ cat prefecture.txt

北海道(ほっかいどう) 札幌(さっぽろ)
青森県(あおもり) 青森(あおもり)
岩手県(いわて) 盛岡(もりおか)
宮城県(みやぎ) 仙台(せんだい)
秋田県(あきた) 秋田(あきた)
山形県(やまがた) 山形(やまがた)
福島県(ふくしま) 福島(ふくしま)
        :
        :
        :
  • |で出力結果をgrepに渡す
$ cat prefecture.txt | grep 東京都
東京都(とうきょう) 東京(とうきょう)

おわり

参照

Linuxコマンドを連続して使うには

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20