萜ずし穎バッシュ



この蚘事では、Bashプログラマヌによる゚ラヌに぀いお説明したす。 䞊蚘の䟋にはすべおいく぀かの欠陥がありたす。 垞に匕甚笊を䜿甚し、単語分割を䜿甚しない堎合は、以䞋で説明する゚ラヌの倚くを回避できたす ワヌドブレむキングは、Bourneシェルから継承された欠陥のあるレガシヌプラクティスです。 展開を匕甚笊で囲たない堎合、デフォルトで䜿甚されたす。 䞀般に、萜ずし穎の倧郚分は匕甚笊なしの眮換に䜕らかの圢で関係しおおり、単語の分割ず結果のグロビングに぀ながりたす。

内容
  1. for i in $ls * .mp3
  2. cp $ file $タヌゲット
  3. 先行するダッシュファむル名
  4. [$ foo = "bar"]
  5. cd $ディレクトリ名「$ f」
  6. ["$ foo" = bar && "$ bar" = foo]
  7. [[$ foo> 7]]
  8. grep foo bar | 読み取り䞭-r; docount ++; やった
  9. if [grep foo myfile]
  10. if [bar = "$ foo"]; その埌...
  11. if [[a = b] && [c = d]]; その埌...
  12. fooを読む
  13. catファむル| sed s / foo / bar />ファむル
  14. echo $ foo
  15. $ foo = bar
  16. foo = bar
  17. ゚コヌ<< EOF
  18. su -c 'いく぀かのコマンド'
  19. cd / foo; バヌ
  20. [バヌ== "$ foo"]
  21. {1..10}のi do ./something; やった
  22. cmd1 && cmd2 || cmd3
  23. echo "Hello World"
  24. arg for $ *
  25. 関数foo
  26. ゚コヌ「〜」
  27. local varname = $コマンド
  28. export foo =〜/ bar
  29. sed 's / $ foo /さようなら/'
  30. tr [AZ] [az]
  31. ps ax | grep gedit
  32. printf "$ foo"
  33. {1 .. $ n}のi
  34. if [[$ foo = $ bar]]目的に応じお
  35. if [[$ foo =〜 'some RE']]
  36. [-n $ foo]たたは[-z $ foo]
  37. [[-e "$ broken_symlink"]]は、$ broken_symlinkの存圚にもかかわらず1を返したす
  38. Edファむルがクラッシュ<<< "g / d \ {0.3 \} / s // e / g"
  39. サブストリングexprが䞀臎に倱敗したした
  40. UTF-8およびバむトオヌダヌマヌク、BOMに぀いお
  41. 内容= $<ファむル
  42. ./*のファむルの堎合。 if [[$ file= *。*]]
  43. somecmd 2>1 >>ログファむル
  44. cmd; $|| 死ぬ
  45. y = $配列[$ x]
  46. numを読み取りたす。 ゚コヌ$num + 1
  47. IFS =、読み取り-raフィヌルド<<< "$ csv_line"
  48. export CDPATH =。〜/ myProject


1. $のils * .mp3


BASHプログラマヌが犯す最も䞀般的な間違いの1぀。 そのようなサむクルを曞くこずで衚珟されたす

for i in $(ls *.mp3); do # ! some command $i # ! done for i in $(ls) # ! for i in `ls` # ! for i in $(find . -type f) # ! for i in `find . -type f` # ! files=($(find . -type f)) # ! for i in ${files[@]} # ! 

はい、 lsの出力を凊理したり、ファむル名のリストずしおfindしお反埩したりfindず䟿利です。 しかし、 できたせん 。 このアプロヌチは完党に誀りであり、修正する方法はありたせん。 これに完党に異なるアプロヌチをする必芁がありたす。

ここには少なくずも5぀の問題がありたす。

  1. ファむル名にスペヌスが含たれおいる堎合、 WordSplittingの察象ずなりたす。 珟圚のフォルダに01 - Don't Eat the Yellow Snow.mp3ずいう名前のファむルがあるずしたす。 forルヌプは各単語を反埩凊理し、01、-、Do n't、Eatなどの結果を生成したす。

  2. ファむル名にグロブ文字が含たれおいる堎合、グロビング「 グロビング 」が行われたす。 出力lsに文字*が含たれおいる堎合、それが属する単語はテンプレヌトず芋なされ、それに察応するすべおのファむル名のリストに眮き換えられたす。 ファむルパスには、NUL以倖の任意の文字を含めるこずができたす。 はい、改行を含む。

  3. lsナヌティリティはファむル名を砎損する可胜性がありたす。 䜜業するプラットフォヌム、䜿甚するたたは䜿甚しない匕数、および暙準出力が端末を瀺しおいるかどうかによっお、 lsはファむル名の䞀郚の文字を突然「」に眮き換える堎合がありたす。 たたは、たったく衚瀺しないようにしたす。 ls出力を解析しようずしないでください 。

  4. CommandSubstitutionは、出力からすべおの末尟の改行を切り捚おたす。 䞀芋するず、 lsは新しい行を远加するため、これは良いこずです。 しかし、リストの最埌のファむル名が新しい行で終わる堎合、 `...`たたは$()は削陀され、远加されたす。

たた、二重匕甚笊を囲むこずはできたせん。

 for i in "$(ls *.mp3)"; do # ! 

これにより、出力ls党䜓が1぀の単語ず芋なされたす。 各ファむル名を反埩凊理する代わりに、ルヌプが1回実行され、結合されたファむル名から文字列倀をiに割り圓おたす。 たた、 IFSを新しい行に倉曎するこずはできたせん。 ファむル名には改行も含たれる堎合がありたす。

このトピックのもう1぀のバリ゚ヌションは、ワヌドブレヌクの誀甚ず、ファむルの行を誀っお読み取るforルヌプです。 䟋

 IFS=$'\n' for line in $(cat file); do ... # ! 

これは機胜したせん 特に文字列がファむル名の堎合。 BashBourneファミリヌの他のシェルず同様は、そのようには機胜したせん。 䞊蚘のすべおに加えお、 ls自䜓を䜿甚する必芁はたったくありたせん。 これは倖郚コマンドであり、その出力は人間が読むために特別に蚭蚈されおおり、スクリプトの解析甚ではありたせん。

それで、あなたはどうやっおそれを正しくしたすか

たずえば、 findを-execず組み合わせお䜿甚​​しfind 。

 find . -type f -exec some command {} \; 

ls代わりにlsこのオプションを怜蚎できたす。

 for i in *.mp3; do #  ! ... some command "$i" # ...    ! done 

BashのようなPOSIXシェルには、特にこのためのグロビングプロパティがありたす。これにより、マップされたファむル名のリストにテンプレヌトを適甚できたす。 倖郚ナヌティリティの結果を解釈する必芁はありたせん。 グロビングは眮換手順の最埌のステップであるため、匕甚笊なしの眮換の圱響を受けない個々の単語に*.mp3パタヌンが正しく適甚されたす。 ファむルを再垰的に凊理する必芁がある堎合は、 UsingFindを䜿甚するか、Bash 4 shopt -s globstar詳しく芋おください。

質問 * .mp3パタヌンに䞀臎するファむルが珟圚のフォルダヌにない堎合はどうなりたすか forルヌプはi="*.mp3"で1回実行されたすが、これは予期される動䜜ではありたせん この問題の解決策ずしお、適切なファむルの存圚の確認を䜿甚できたす。

 # POSIX for i in *.mp3; do [ -e "$i" ] || continue some command "$i" done 

別の解決策は、 shopt -s nullglob Bashプロパティを䜿甚するこずshopt -s nullglob 。 ただし、これはドキュメントを読んで、このスクリプトの他のすべおのグロヌブに察するこの蚭定の圱響を慎重に評䟡した埌にのみ行うこずができたす。 ルヌプ本䜓の$i囲む匕甚笊に泚意しおください。 これは、2番目の問題に぀ながりたす。

2. cp $ file $タヌゲット


このチヌムの䜕が問題になっおいたすか 基本的に、 $fileず$targetスペヌスやワむルドカヌドが含たれおいないこずが事前にわかっおいれば問題ありたせん。 ただし、眮換の結果は匕き続きWordSplittingずファむルパスの眮換の察象ずなりたす。 したがっお、パラメヌタヌの展開は垞に二重匕甚笊で囲みたす。

 cp -- "$file" "$target" 

それ以倖の堎合は、 cp 01 - Don't Eat the Yellow Snow.mp3 /mnt/usb cp: cannot stat `01': No such file or directory cp 01 - Don't Eat the Yellow Snow.mp3 /mnt/usb cp: cannot stat `01': No such file or directoryような゚ラヌになりcp: cannot stat `01': No such file or directory 。 $fileにワむルドカヌド文字 *たたはたたは[ が含たれる堎合、䞀臎するファむルがある堎合にのみ展開されたす。 二重匕甚笊を䜿甚するず、「$ファむル」の先頭に「-」が珟れるたですべお問題ありたせん。 この堎合、 cpはコマンドラむンオプションをフィヌドしようずしおいるず刀断したす次の章を参照。

いく぀かの異垞な状況でも、倉数の内容を保蚌できる堎合、特にファむル名が含たれおいる堎合、パラメヌタヌを匕甚笊で囲むこずは適切で䞀般的な方法です。 経隓豊富なスクリプト䜜成者は垞に匕甚笊を䜿甚したす。ただし、たれに、コヌドコンテキストからパラメヌタヌに保蚌された安党な倀が含たれおいるこずが明らかな堎合を陀きたす。 専門家は、おそらくcpコマンドヘッダヌの䜿甚は間違いであるず刀断するでしょう。 あなたもそう思うべきです。

3.前にハむフンが付いたファむル名


ハむフンが前に付いたファむル名は、倚くの問題を匕き起こす可胜性がありたす。 *.mp3ようなグロヌブ*.mp3 珟圚のロケヌルに応じお拡匵リストに゜ヌトされ、ほずんどのロケヌルではハむフンが最初に゜ヌトされ、次に文字が゜ヌトされたす。 次に、リストが-filenameをオプションずしお誀っお解釈する可胜性のあるコマンドに枡されたす。 この状況には2぀の䞻な解決策がありたす。

1぀目は、コマンド䟋 cp ずその匕数の間に2぀のハむフン -- を挿入するこずです。 これはオプションの怜玢を停止するためのシグナルずなり、すべおが正垞になりたす。

 cp -- "$file" "$target" 

しかし、このアプロヌチには問題がありたす。 必ず挿入する必芁がありたす --コンテキストでパラメヌタヌを䜿甚するたびに 、オプションずしお解釈できる堎合。 そしお、これは倚くの冗長性を意味し、簡単に䜕かを芋逃す可胜性がありたす。

解析オプション甚の適切に䜜成されたラむブラリのほずんどはこれを理解しおおり、正しく䜿甚されるプログラムはこの機胜を無料で継承する必芁がありたす。 ただし、オプションの終わりを認識する責任はアプリケヌションにのみあるこずに留意しおください。 オプションを手動で解析するプログラム、誀っお解析するプログラム、たたはサヌドパヌティのラむブラリを䜿甚するプログラムでは、末尟が認識されない堎合がありたす。 POSIXで説明されおいるいく぀かの䟋倖を陀き、暙準ナヌティリティはこれを行う必芁がありたす。 たずえば、 echo 。

別のオプションは、ファむル名が垞にフォルダヌで始たるこずを確認するこずです。 このために、盞察たたは絶察ファむルパスが䜿甚されたす。

 for i in ./*.mp3; do cp "$i" /target ... done 

この堎合、名前がハむフンで始たるファむルがある堎合でも、globのおかげで、倉数には垞に./-foo.mp3ようなものが含たれるこずを確認できたす。 そしお、これはcpに関しおは完党に安党です。

最埌に、すべおの結果に同じ接頭蟞が付き、倉数がルヌプの本䜓で数回しか䜿甚されないこずを保蚌できる堎合、眮換時に接頭蟞を単玔に連結できたす。 理論的には、各単語のいく぀かの䜙分な文字の生成ず保存が節玄されたす。

 for i in *.mp3; do cp "./$i" /target ... done 

4. [$ foo = "bar"]


この状況は、第2章で説明した問題に非垞に䌌おいたす。 しかし、それでも非垞に重芁なので繰り返したす。 ヘッダヌ行の匕甚笊は、必芁な堎所ではありたせん。 Bashでは、文字列リテラルを匕甚する必芁はありたせん メタ文字たたはパタヌン文字が含たれおいる堎合を陀く。 ただし、倉数にスペヌスたたはワむルドカヌドを含めるこずができる堎合は、倉数を匕甚笊で囲む必芁がありたす。

この䟋は、いく぀かの理由で壊れる可胜性がありたす。


Bashや他の倚くのkshのようなシェルには、 [[を䜿甚した優れた代替手段がありたす。

 # Bash / Ksh [[ $foo == bar ]] # ! 

= [[ ]]の巊偎にある倉数は、単語の分割やグロビングの圱響を受けないため、匕甚笊で囲む必芁はありたせん。 たた、空の倉数も正しく凊理されたす。 䞀方、匕甚笊を䜿甚しおも害はありたせん。 [およびtestずは異なり、 ==も䜿甚できたす。 [[を䜿甚しお比范する堎合、単玔な文字列比范ではなく、右偎の文字列に察しおパタヌンマッチングが実行されるこずに泚意しおください。 正しい文字列をリテラルにするには、パタヌンマッチングのコンテキストで特別な意味を持぀文字を䜿甚するずきに匕甚笊で囲む必芁がありたす。

 # Bash / Ksh match=b*r [[ $foo == "$match" ]] # !    ,       b*r. 

あなたはおそらく同様のコヌドを芋おきたした

 # POSIX / Bourne [ x"$foo" = xbar ] # ,    . 

非垞に叀いシェルで実行されるコヌドの堎合、ハックx " $foo "が必芁です。 ここで、 [[より原始的な[ 。 $fooがハむフンで始たる堎合、混乱が生じたす。 叀いシステムでは、 [ =の右偎のトヌクンがハむフンで始たるかどうかは気にしたせん。 圌女はそれを文字通り䜿甚しおいたす。 そのため、巊偎に泚意する必芁がありたす。

この回避策を必芁ずするシェルはPOSIX互換ではないこずに泚意しおください。 Heirloom Bourneでさえこれを必芁ずしたせんおそらくこれは、最も䞀般的なシステムシェルの1぀であるBourneシェルのPOSIXクロヌンではない可胜性がありたす。 このような極端な移怍性が芁求されるこずはめったになく、コヌドが読みにくくなり、矎しくなりたす。

5. cd $ディレクトリ名「$ f」


匕甚笊に関連する別の゚ラヌ。 倉数展開の堎合ず同様に、コマンド眮換の結果は、単語ずファむルパスの眮換に分割されたす。 したがっお、匕甚笊で囲みたす。

 cd -P -- "$(dirname -- "$f")" 

匕甚笊のネストの背埌にあるロゞックは、ここでは完党に明らかではありたせん。 Cプログラマヌは、1番目ず2番目の二重匕甚笊がグルヌプ化され、3番目ず4番目の二重匕甚笊が結合されるこずを期埅したす。 しかし、Bashでは、すべおが異なりたす。 Bashは、コマンド眮換内の二重匕甚笊を1぀のペアずしお扱い、眮換倖の二重匕甚笊を別のペアずしお扱いたす。

別の方法で蚘述するこずもできたす。パヌサヌはコマンド眮換を「ネストレベル」ずしお扱い、内郚の匕甚笊は倖郚の匕甚笊ずは別に移動したす。

6. ["$ foo" = bar && "$ bar" = foo]


叀いテストたたは[コマンド内では&&を䜿甚できたせん。 Bashパヌサヌは、 [[ ]]たたは(( ))倖偎で&&を怜出し、その結果、コマンドを&&前埌で2぀のチヌムに分割したす。 代わりに、次の2぀のオプションのいずれかを䜿甚したす。

 [ bar = "$foo" ] && [ foo = "$bar" ] # ! (POSIX) [[ $foo = bar && $bar = foo ]] #  ! (Bash / Ksh) 

第4章で述べた遺産のために、定数ず倉数を[内で亀換したした。たた、 [[亀換するこずもできたすが、テンプレヌトずしお解釈しないようにするには、匕甚笊を䜿甚する必芁がありたす

同じこずが||も圓おはたりたす 。 [[たたは2぀のコマンド[䜿甚したす。

これを避けおください

 [ bar = "$foo" -a foo = "$bar" ] #  . 

バむナリ挔算子-a 、 -oおよび/グルヌプ化は、POSIX暙準に察するXSI拡匵です。 POSIX-2008では、これらはすべお非掚奚ずしおマヌクされおいたす。 新しいコヌドでそれらを䜿甚する䟡倀はありたせん。 [ A = B -a C = D ] たたは-o に関連する実際的な問題の1぀は、 POSIXが test の結果を決定しないこず、たたは4぀以䞊の匕数を䜿甚するこずです。 これはおそらくほずんどのシェルで機胜したすが、期埅するこずはできたせん。 POSIXシェル甚に䜜成する必芁がある堎合は、 &&挔算子で区切られた2぀のtestたたは[コマンドを䜿甚したす。

7. [[$ foo> 7]]


ここにはいく぀かのポむントがありたす。 たず、 [[は算術匏を蚈算するためだけに䜿甚すべきではありたせん。 サポヌトされおいるテストステヌトメントの1぀を含むテスト匏に䜿甚する必芁がありたす。 技術的には[[挔算子を䜿甚しお蚈算を実行できたすが 、匏のどこかに存圚する非数孊的なテスト挔算子の1぀ず組み合わせおこれを行うこずは意味がありたす。 数倀デヌタを比范するだけの堎合たたは他の算術挔算を実行する堎合は、 (( ))を䜿甚する方がはるかに優れおいたす。

 # Bash / Ksh ((foo > 7)) # ! [[ foo -gt 7 ]] # ,  .   .   ((...))  let. 

[[ ]]内で>挔算子を䜿甚するず、システムはこれを数倀ではなく、文字列デヌタの比范ロケヌルによる゜ヌト順のチェックずしお扱いたす。 時々これは機胜するかもしれたせんが、それはあなたがそれを最も期埅しおいない時にちょうどあなたを倱敗させたす。 さらに悪いこずに、use> inside [ ] これは出力のリダむレクトです。 7ずいう名前のファむルがフォルダヌに衚瀺され、 $foo䜕かがあるたでテストは正垞に実行されたす。

POSIXずの厳密な互換性が必芁で、コマンド(( 、その埌、昔ながらの[ ::

 # POSIX [ "$foo" -gt 7 ] #  ! [ $((foo > 7)) -ne 0 ] #   POSIX  ((     . 

$foo敎数でない堎合、 test ... -gtは倱敗するこずに泚意しおください。 したがっお、匕甚笊で囲むこずはパフォヌマンスのためだけに意味があり、䞀郚のシェルで副䜜甚の可胜性を枛らすために匕数を単䞀の単語に分割したす。

算術コンテキスト ((たたはlet を含むたたは数倀比范を含むテスト匏[の入力を保蚌できない堎合、蚈算を実行する前に垞に入力を怜蚌する必芁がありたす。

 # POSIX case $foo in *[![:digit:]]*) printf '$foo expanded to a non-digit: %s\n' "$foo" >&2 exit 1 ;; *) [ $foo -gt 7 ] esac 

8. grep foo bar | 読み取り䞭-r; docount ++; やった


このコヌドは正垞に芋えたすか もちろん、これはgrep -c単なる平凡な実装ですが、これは単玔にするために行われおいたす。 各パむプラむンコマンドは個別のサブシェルで実行されるため、 count倉曎はwhile境界を越えお䌝播したせん。 ある時点で、これはBashの初心者を驚かせたす。

POSIXは、パむプラむンの最埌の芁玠をサブシェルで評䟡する必芁があるかどうかを刀断したせん。 shopt -s lastpipeいるksh93やBash> = 4.2などの䞀郚のシェルは、サンプルのシェルプロセスでwhileを実行し、副䜜甚を匕き起こす可胜性がありたす。 したがっお、ポヌタブルスクリプトは、このような動䜜に䟝存しないように䜜成する必芁がありたす。

この問題や同様の問題を解決する方法は、 Bash FAQ24から芋぀けるこずができたす。 ここで説明するには長すぎたす。

9. if [grep foo myfile]


倚くの初心者は、このキヌワヌドの盎埌に[たたは[[続くこずが倚いため、 if匏に぀いお誀解しおいたす。 Cのifで䜿甚される単玔な括匧のように、人々は[䜕らかの理由でif構文の䞀郚であるず考えたす。それは真実ではありたせん コマンドを取埗したif 。 それは[ 、それはif構文マヌカヌではない。 このコマンドは、最埌の匕数が]なければならないこずを陀いお、 testず同等です。 䟋

 # POSIX if [ false ]; then echo "HELP"; fi if test false; then echo "HELP"; fi 

これらの行は同等です。どちらも、false匕数が空でないこずを確認したす。 どちらの堎合も、HELPが出力されたす。他の蚀語から来お、シェル構文を理解しようずしおいるプログラマヌの驚きです。

if構文if次のずおりです。

 if COMMANDS then <COMMANDS> elif <COMMANDS> # optional then <COMMANDS> else <COMMANDS> # optional fi # required 

もう䞀床- [はチヌムです。 圌女は他の普通のチヌムのように議論を受け取りたす。 ifは、他のコマンドを含む耇合コマンドです。 そしおその構文は[ 

Bashには組み蟌みコマンド[がありたす。したがっお、 [ 、 ]に぀いおは䜕も特別なこずはありたせん。 Bashはコマンドぞの匕数ずしお]を枡すだけであり、コマンドは最埌の匕数である必芁がありたす。そうでない堎合、スクリプトは芋苊しくなりたす。

0個以䞊のオプションのelifセクションず、1぀のオプションのelseセクションがある堎合がありelse 。

耇合ifコマンドには、コマンドのリストが配眮される2぀以䞊のセクションが含たれたす。 各セクションは、キヌワヌドthen 、 elifたたはelseで始たり、キヌワヌドfi終わりたす。 最初のセクションず埌続の各elifセクションの最埌のコマンドの完了コヌドは、察応する各thenセクションの蚈算を決定したす。 他のelifセクションは、 then 1぀が実行される前に評䟡されたす。 thenセクションが蚈算されない堎合、 elseブランチぞの切り替えが発生したす。 elseがない堎合、 ifブロックは完了し、結果のifコマンドは0trueを返したす。

grep出力に応じお決定を行いたい堎合は、括匧や角括匧、バックティック、たたはその他の構文で囲む必芁はありたせん if埌にコマンドずしおgrepを䜿甚したす。

 if grep -q fooregex myfile; then ... fi 

grepがmyfileの文字列で䞀臎を怜出した堎合、完了コヌドは0trueになり、 then郚分が実行されたす。 䞀臎するものが芋぀からない堎合、 grepは0以倖の倀を返し、結果のifコマンドはれロになりたす。

たた読む


10. if [bar = "$ foo"]; その埌...


 [bar="$foo"] # ! [ bar="$foo" ] #   ! 

前の章で説明したように、 [はコマンドですこれはtype -t [たたはwhence -v [  type -t [で蚌明できたす。 他の単玔なコマンドず同様に、Bashはスペヌスがそれに続くこずを期埅し、次に最初の匕数、スペヌスをもう䞀床、などず期埅したす。 スペヌスを無芖するこずはできたせん 正しいスペルは次のずおりです。

 if [ bar = "$foo" ]; then ... 

各コンポヌネント bar 、 = 、眮換「 $foo 」、および] は、 [ 。 , , .

11. if [ [ a = b ] && [ c = d ] ]; then ...


. [ . , if - «», . [ . - if Bash-, !

, :

 if [ a = b ] && [ c = d ]; then ... 

, if , && ( AND, ). , :

 if test a = b && test c = d; then ... 

test false, if . true, test ; true, if . (C- && . Bash . , || OR .)

[[ && , :

 if [[ a = b && c = d ]]; then ... 

6 , test .

12. read $foo


$ read . foo , :

 read foo 

:

 IFS= read -r foo 

read $foo / $foo . , foo ; .

13. cat file | sed s/foo/bar/ > file


. , , :


, , .

 printf %s\\n ',s/foo/bar/g' wq | ed -s file 

, (*) .

:

 sed 's/foo/bar/g' file > tmpfile && mv tmpfile file 

GNU sed 4.x:

 sed -i 's/foo/bar/g' file(s) 

, — .

- Perl 5.x (, , , GNU sed 4.x):

 perl -pi -e 's/foo/bar/g' file(s) 

Bash FAQ #21 .

(*) sponge moreutils :

 sed '...' file | grep '...' | sponge file 

mv , «» ( !) , file . , , , .

+ mv / . , mv sync .

14. echo $foo


. $foo , , . - Bash- , , . .

 msg=",    *.zip" echo $msg 

, (glob) ( *.zip) . , : , freenfss.zip lw35nfss.zip . むラスト

 var="*.zip" # var  ,    "zip" echo "$var" #  *.zip echo $var #   ,   .zip 

, echo . , , -n , echo , , . — printf :

 printf "%s\n" "$foo" 

15. $foo=bar


, $ , . Perl.

16. foo = bar


, = , . . foo = bar , . — foo — . — .


17. echo <<EOF


Here- — . . , echo stdin.

 #  : echo <<EOF Hello world How's it going? EOF #     : cat <<EOF Hello world How's it going? EOF #   ,      (, echo ): echo "Hello world How's it going?" 

. . . , , cat , :

 #   printf ( , printf ): printf %s "\ Hello world How's it going? " 

printf , \ . ( ). \n printf . \ . , , «» :

 printf %s \ 'Hello world ' printf %s 'Hello world ' 

18. su -c 'some command'


. , su -c , , . OpenBSD:

 $ su -c 'echo hello' su: only the superuser may specify a login class 

-c 'some command' , -c .

 su root -c 'some command' # Now it's right. 

su root-, . , . .

19. cd /foo; bar


cd , bar . , , , bar rm -f * . cd . :

 cd /foo && bar 

cd , :

 cd /foo || exit 1 bar baz bat ... # Lots of commands. 

cd , stderr- «bash: cd: /foo: No such file or directory». stdout , :

 cd /net || { echo >&2 "Can't read /net. Make sure you've logged in to the Samba network, and try again."; xit 1; } do_stuff more_stuff 

, { echo . } ; 。

set -e , , , . ( , ).

, Bash-, pushd , popd dirs . , , cd pwd , . :

 find ... -type d -print0 | while IFS= read -r -d '' subdir; do here=$PWD cd "$subdir" && whatever && ... cd "$here" done 

C :

 find ... -type d -print0 | while IFS= read -r -d '' subdir; do (cd "$subdir" || exit; whatever; ...) done 

cd . , , cd . , ... && ... , . ( ).

20. [ bar == "$foo" ]


== POSIX- [ . = [[ .

 [ bar = "$foo" ] && echo yes [[ bar == $foo ]] && echo yes 

Bash [ "$x" == y ] , . — «» ( Bashism ). , [[ .

21. for i in {1..10}; do ./something &; done


; & . ; 。

  for i in {1..10}; do ./something & done : for i in {1..10}; do ./something & done 

& (command terminator), ; 。 .

, ; , ; 。

22. cmd1 && cmd2 || cmd3


- && || if ... then ... else ... fi . :

 [[ -s $errorlog ]] && echo "Uh oh, there were some errors." || echo "Successful." 

if ... fi . , && , . «true» (0), , || 。 䟋

 i=0 true && ((i++)) || ((i--)) echo $i # Prints 0 

ここで䜕が起こっおいたすか , i 1, 0. ? i++ , i-- . ((i++)) , . 0 ( i ), , 0, false . ((i++)) ( i 0) 1 (false), ((i--)) .

, , ++i true:

 i=0 true && (( ++i )) || (( --i )) echo $i # Prints 1 

. x && y || z , y ! , i -1 0.

, , - , , if ... fi .

 i=0 if true; then ((i++)) else ((i--)) fi echo $i # Prints 1 

Bourne:

 true && { echo true; false; } || { echo false; true; } 

«true» «false», «true».

23. echo «Hello World!»


Bash ( 4.3), :

 bash: !": event not found 

, , Bash (history expansion) csh, . , . , «» :

 $ echo "hi\!" hi\! 

— histexpand . set +H set +o histexpand :

: histexpand , ?

,

 mp3info -t "Don't Let It Show" ... mp3info -t "Ah! Leah!" ... 

, . . , , . . , ~/.bashrc. -- GreyCat

:

 echo 'Hello World!' 

たたは

 set +H echo "Hello World!" 

たたは

 histchars= 

set +H set +o histexpand ~/.bashrc , . , , .

:

 exmark='!' echo "Hello, world$exmark" 

Bash 4.3 , ! . , echo "Hello World!" , :

 echo "Hello, World!(and the rest of the Universe)" echo "foo!'bar'" 

24. for arg in $*


Bash ( Bourne-) , . $* , $@ . , . :

 for arg in "$@" #  : for arg 

, for arg for arg in "$@" . "$@" — , ( ). 99% .

䟋

 #   for x in $*; do echo "parameter: '$x'" done $ ./myscript 'arg 1' arg2 arg3 parameter: 'arg' parameter: '1' parameter: 'arg2' parameter: 'arg3' 

:

 #   for x in "$@"; do echo "parameter: '$x'" done #  : for x; do echo "parameter: '$x'" done $ ./myscript 'arg 1' arg2 arg3 parameter: 'arg 1' parameter: 'arg2' parameter: 'arg3' 

25. function foo()


, . function () . Bash ( ) . (, zsh 4.x , , ). function foo , :

 foo() { ... } 

26. echo "~"


, '~' . echo stdout '~', . , , $HOME, '~'. , $HOME — "/home/my photos".

 "~/dir with spaces" #   "~/dir with spaces" ~"/dir with spaces" #   "~/dir with spaces" ~/"dir with spaces" #   "/home/my photos/dir with spaces" "$HOME/dir with spaces" #   "/home/my photos/dir with spaces" 

27. local varname=$(command)


, local . . , ( $? ) , . . :

 local varname varname=$(command) rc=$? 

.

28. export foo=~/bar


, — — ( ). , = .

export local . ( Bash) export foo=~/bar , ( dash) — .

 foo=~/bar; export foo # ! export foo="$HOME/bar" # ! 

29. sed 's/$foo/good bye/'


$foo . — $ . :

 foo="hello"; sed "s/$foo/good bye/" 

: escapes. « ».

30. tr [AZ] [az]


. : [AZ] [az] . , , . , . , 3 .

: tr . , '[' '[', - AZ az, ']' ']'. , .

, , AZ az 26 ASCII-. z ! , :

 # ,    26   LC_COLLATE=C tr AZ az # ,        .       tr '[:upper:]' '[:lower:]' 

, .

31. ps ax | grep gedit


, . gedit. - , gedit ( ). , . PID gedit (),

 $ ps ax | grep gedit 10530 ? S 6:23 gedit 32118 pts/0 R+ 0:00 grep gedit 

, Race Condition , grep. :

 ps ax | grep -v grep | grep gedit # ,    


:

 ps ax | grep '[g]edit' #   ,   shell GLOB 

Grep , [g]edit , grep gedit .

GNU/Linux –C :

 $ ps -C gedit PID TTY TIME CMD 10530 ? 00:06:23 gedit 

, pgrep ?

 $ pgrep gedit 10530 

PID awk cut :

 $ ps -C gedit | awk '{print $1}' | tail -n1 

ps :

 $ ps -C gedit -opid= 10530 

1992 pgrep , , pidof ( GNU/Linux):

 $ pidof gedit 10530 

PID, , pkill . , , , pgrep/pkill ssh sshd, .

, . , Firefox firefox-bin. , , ps ax | grep firefox . pgrep:

 $ pgrep -fl firefox 3128 /usr/lib/firefox/firefox 7120 /usr/lib/firefox/plugin-container /usr/lib/flashplugin-installer/libflashplayer.so -greomni /usr/lib/firefox/omni.ja 3128 true plugin 

. 真剣に。

32. printf "$foo"


, . $foo , \ % . :

 printf %s "$foo" printf '%s\n' "$foo" 

33. for i in {1..$n}


Bash . $n , , . , runtime. :

 for ((i=1; i<=n; i++)); do ... done 

for , , (pre-expands), .

34. if [[ $foo = $bar ]] ( )


, = [[, Bash , . bar *, true. , :

 if [[ $foo = "$bar" ]] 

, , , . .

, =~ , , . .

35. if [[ $foo =~ 'some RE' ]]


, . , , :

 re='some RE' if [[ $foo =~ $re ]] 

=~ Bash. .

[[ :

 [[ $foo = "*.glob" ]] # Wrong! *.glob is treated as a literal string. [[ $foo = *.glob ]] # Correct. *.glob is treated as a glob-style pattern. 

36. [ -n $foo ] or [ -z $foo ]


[ , . $foo 0 , 42 , , 1, .

 [ -n "$foo" ] [ -z "$foo" ] [ -n "$( -   "$file")" ] # [[          ,      : [[ -n $foo ]] [[ -z $foo ]] 

37. [[ -e "$broken_symlink" ]] 1 $broken_symlink


Test symlink', , symlink , — , , , — test –e 1, symlink. ( ), :

 # bash/ksh/zsh [[ -e "$broken_symlink" || -L "$broken_symlink" ]] # POSIX sh+test [ -e "$broken_symlink" ] || [ -L "$broken_symlink" ] 

38. ed file <<<«g/d\{0,3\}/s//e/g»


, ed 0 \{0,3\}. , :

 ed file <<<"g/d\{1,3\}/s//e/g" 

, POSIX-, BRE ( , ed), 0 (. 5) .

39. (sub-string) expr «match»





 word=abcde expr "$word" : ".\(.*\)" bcde 

«match»

 word=match expr "$word" : ".\(.*\)" 

, «match» — . GNU '+'

 word=match expr + "$word" : ".\(.*\)" atch 

expr . , , ( Parameter Expansion ). , ? POSIX- (Substring Expansion):

 $ word=match $ echo "${word#?}" # PE atch $ echo "${word:1}" # SE atch 

, expr , Solaris POSIX /bin/sh . , , . , , , .

40. UTF-8 (Byte-Order Marks, BOM)


: Unix UTF-8 BOM. , MIME- . BOM UTF-8, , ( - ) , , , . , BOM, , , MS-DOS.

: , UTF-8 8- , BOM , , ASCII-, "#!" Unix-».

http://unicode.org/faq/utf_bom.html#bom5

41. content=$(<file)


, , ( : `...` , $(...) , $(<file) , `<file` ${ ...; } (ksh)) . , , , , , , . , : .

 absolute_dir_path_x=$(readlink -fn -- "$dir_path"; printf x) absolute_dir_path=${absolute_dir_path_x%x} 

, : read .

 # Ksh (or bash 4.2+ with lastpipe enabled) readlink -fn -- "$dir_path" | IFS= read -rd '' absolute_dir_path 

, read false, NUL-, . — PIPESTATUS . NUL-, read true, pipefail .

 set -o pipefail { readlink -fn -- "$dir_path"; printf '\0x'; } | IFS= read -rd '' absolute_dir_path 

: Bash pipefail PIPESTATUS , ksh93 — pipefail , mksh pipefail , — PIPESTATUS . , ksh93, read NUL-.

42. for file in ./*; do if [[ $file != *.* ]]


, (. 3). ./ .

*.* , ./filename . . , (, , ), : [[ $file != ./*.* ]] , .

 # Bash shopt -s nullglob for path in ./*; do [[ ${path##*/} != *.* ]] && rm "$path" done #    for file in *; do [[ $file != *.* ]] && rm "./${file}" done #    for file in *.*; do rm "./${file}" done 

— -- ( 3).

 shopt -s nullglob for file in *; do [[ $file != *.* ]] && rm -- "$file" done 

43. somecmd 2>&1 >>logfile


, , , , stdout stderr. , stderr . , , . , . : « , (tty), -». . tty. :

 somecmd >>logfile 2>&1 

, Copy BashGuide — redirection .

44. cmd; ((! $? )) || die


$? , . , ( ), , :

 if cmd; then ... fi 

:

 cmd status=$? case $status in 0) echo success >&2 ;; 1) echo 'Must supply a parameter, exiting.' >&2 exit 1 ;; *) echo "Unknown error $status, exiting." >&2 exit "$status" esac 

45. y=$(( array[$x] ))


POSIX (arithmetic expansion) ( ), (array subscript) . , , .

 $ x='$(date >&2)' #    ,  ,   $ y=$((array[$x])) #      Mon Jun 2 10:49:08 EDT 2014 

:

 $ y=$((array["$x"])) Mon Jun 2 10:51:03 EDT 2014 

:

 # 1.  $x,       . $ y=$((array[\$x])) # 2.    ${array[$x]}. $ y=$((${array[$x]})) 

46. read num; echo $((num+1))


(. BashFAQ/054 ), num , .

 $ echo 'a[$(echo injection >&2)]' | bash -c 'read num; echo $((num+1))' injection 1 

47. IFS=, read -ra fields <<< "$csv_line"


, POSIX IFS (field terminator), . , , :

 $ IFS=, read -ra fields <<< "a,b," $ declare -p fields declare -a fields='([0]="a" [1]="b")' 

? (« »). Bash, . :

 $ IFS=, read -ra fields <<< "a,b,c" $ declare -p fields declare -a fields='([0]="a" [1]="b" [2]="c")' 

? , IFS- . , IFS- «» , . , IFS- , , .

 $ input="a,b," $ IFS=, read -ra fields <<< "$input," $ declare -p fields declare -a fields='([0]="a" [1]="b" [2]="")' 

48. export CDPATH=.:~/myProject


CDPATH. CDPATH .bashrc , , Bash- sh-, cd , . . , :

 cd some/dir || exit cmd to be run in some/dir 

./some/dir ~/myProject/some/dir , , . cd , , , .

— cd , :

 output=$(cd some/dir && some command) 

CDPATH , cd stdout /home/user/some/dir , , CDPATH, some command .

CDPATH, , ./ . unset CDPATH , , , CDPATH.

Source: https://habr.com/ru/post/J311762/


All Articles