リアクショナリーソフトウェア - by fschmidt

リアクショナリーバッシュチュートリアル


目次


イントロダクション

目次

私は本当にこのチュートリアルを書きたくありませんが、既存のバッシュチュートリアルがあまりにもひどいので、仕方がありません。本、ウェブサイト、YouTubeを見ましたが、どれもひどいです。基本から始めていません。無駄なものがたくさん含まれています。そして、コアコンセプトを説明していません。だから、私はこのリアクショナリープログラミングを学ぶバッシュレッスンのためにこれを書くしかありません。

バッシュシェルの一つで、私が好むものです。私はMacとWindowsに焦点を当てます。Linuxは持っていませんし、嫌いなので、話しません。バッシュのほとんどはMacとWindowsで同じですが、異なる部分については両方を説明します。

バッシュの実行

目次

バッシュへのアクセス方法は、オペレーティングシステムによって異なります。Macの場合、「アプリケーション > ユーティリティ > Terminal.app」にあるMacターミナルを通じてバッシュにアクセスします。デフォルトのシェルをバッシュに設定してください。Windowsの場合はMSYS2をインストールします。デフォルトのターミナルはあまり良くないので、Windowsターミナルを使用することをお勧めします。

はじめに

目次

Macでバッシュを起動すると、次のように表示されます:

Last login: Thu Jan 4 23:25:35 on ttys004 The default interactive shell is now zsh. To update your account to use zsh, please run `chsh -s /bin/zsh`. For more details, please visit https://support.apple.com/kb/HT208050. ~ $

Windows - MSYS2では、次のように表示されます:

~ $

$の行はコマンドプロンプトです。カーソルはその末尾にあり、入力するとテキストがそこに表示されます。$の前に異なるテキストが表示されることがありますが、それは問題ありません。ただし、行は$で終わる必要があります。そうでない場合は、何かが間違っています。

「qqq」と入力してください。「何かを入力」と言った場合は、最後にリターン/エンターを入力してください。リターン/エンターを入力したときにのみ、バッシュは入力した内容を処理します。次のように表示されるはずです:

~ $ qqq -bash: qqq: command not found ~ $

バッシュは「qqq」が何を意味するのか分からず、そのように表示します。次に、以下を試してください... $の後にあるものを入力し、バッシュが示されているように応答するはずです。

~ $ echo hi hi ~ $ echo how are you how are you ~ $ echo bye bye

echoコマンドは、後に続くものをエコーします。次に、キーボードの上矢印を押してください。これにより、カーソルの位置に前のコマンドが表示されます。もう一度上矢印を押すと、その前のコマンドが表示されます。下矢印、左矢印、右矢印を試してください。これを使用して、コマンド履歴をナビゲートできます。削除キーも行の編集に使用できます。そしてもちろん、入力できます。リターン/エンターを押すと、バッシュは編集されたコマンドを取得して処理します。

echo how are youを入力すると、echoはコマンドです。このコマンドには3つの引数があります: howareyou。コマンドと引数はスペースで区切られます。スペースの数は関係ありませんので、次のように:

~ $ echo how are you how are you

echoは引数を1つのスペースで区切って返します。

~ $ echo one; echo two one two

1行に複数のコマンドを;で区切って配置できます。

「man」コマンド

目次

次を入力してください:

~ $ man echo

次のようなものが表示されるはずです:

ECHO(1) BSD General Commands Manual ECHO(1) NAME echo -- write arguments to the standard output SYNOPSIS echo [-n] [string ...] DESCRIPTION The echo utility writes any specified operands, separated by single blank (` ') characters and followed by a newline (`\n') character, to the stan- dard output. The following option is available: -n Do not print the trailing newline character. This may also be achieved by appending `\c' to the end of the string, as is done by iBCS2 compatible systems. Note that this option as well as the effect of `\c' are implementation-defined in IEEE Std 1003.1-2001 (``POSIX.1'') as amended by Cor. 1-2002. Applications aiming for maximum portability are strongly encouraged to use printf(1) to suppress the newline character. :

しかし、Windowsではmanがインストールされていないかもしれません。その場合は、次を行ってください:

~ $ pacman -S man-db

ここで説明されているようにmanをインストールし、再度man echoを試してください。

manコマンドはコマンドのドキュメントを表示します。残念ながら、キーを記憶することに基づいた愚かなユーザーインターフェースを持っているので、必要なキーをいくつかだけ教えます。下矢印と上矢印は1行ずつ下と上に移動します。スペースキーは1ページ下に移動します。そして最も重要なのは、「q」を入力すると終了し、バッシュに戻ります。これを覚えておく必要があります。

次にman manを入力してみてください。表示されるすべての情報は必要ありませんが、複雑なmanページがどのように見えるかを確認できます。他のコマンドのドキュメントを取得するためにmanを使用できます。

ディレクトリ

目次

Mac FinderまたはWindowsファイルエクスプローラーに精通しているはずで、これからディレクトリ(「フォルダ」とも呼ばれる)がツリー状に整理されていることを知っているはずです。

Macの場合:

~ $ pwd /Users/fschmidt ~ $ open . ~ $

Windowsの場合:

~ $ pwd /home/fschmidt ~ $ explorer . ~ $

バッシュを使用する際、常にあるディレクトリにいます。これをカレントディレクトリまたは作業ディレクトリと呼びます。pwdはこのディレクトリへのフルパスを表示します。詳細はman pwdを参照してください。open .はカレントディレクトリのMac Finderを開き、explorer .はカレントディレクトリのWindowsファイルエクスプローラーを開くはずです。

Macで続けます:

~ $ mkdir learn ~ $ cd learn ~/learn $ pwd /Users/fschmidt/learn

mkdirはカレントディレクトリにディレクトリを作成します。作成されたディレクトリがMac FinderまたはWindowsファイルエクスプローラーに表示されるはずです。cdは「ディレクトリを変更する」の略です。これによりカレントディレクトリが変更されます。cdはバッシュに組み込まれたコマンドであり、manは組み込みコマンドには役立たないため、man cdの代わりにhelp cdを試してください。続けます...

~/learn $ pwd /Users/fschmidt/learn ~/learn $ ls ~/learn $ touch file1 ~/learn $ ls file1 ~/learn $ touch file2 ~/learn $ touch file3 ~/learn $ ls file1 file2 file3 ~/learn $ mkdir dir1 ~/learn $ ls dir1 file1 file2 file3 ~/learn $ ls -F dir1/ file1 file2 file3 ~/learn $ ls -a . .. dir1 file1 file2 file3 ~/learn $ ls -a -F ./ ../ dir1/ file1 file2 file3 ~/learn $ ls -aF ./ ../ dir1/ file1 file2 file3

lsはファイルをリストし、touchは空のファイルを作成します。-で始まる引数はオプションです。使用したオプションが何をするかを確認するにはman lsを参照してください。-Fはディレクトリに「/」を追加し、-aは通常隠されている「.」で始まるファイルを表示します。オプションは組み合わせることができます。

~/learn $ ls file1 file1 ~/learn $ ls qqq ls: qqq: No such file or directory ~/learn $ ls file1 qqq file2 ls: qqq: No such file or directory file1 file2 ~/learn $ ls dir1 ~/learn $ touch dir1/d1file ~/learn $ ls dir1 d1file ~/learn $ ls -d dir1 dir1 ~/learn $ ls file1 file2 dir1 file1 file2 dir1: d1file ~/learn $ ls -d file1 file2 dir1 dir1 file1 file2 ~/learn $ ls -dF file1 file2 dir1 dir1/ file1 file2

ファイル引数なしでlsはカレントディレクトリのファイルをリストします。ファイル引数がある場合、それらのファイルが存在する場合にリストします。ファイルがディレクトリの場合、-dオプションが使用されない限り、そのディレクトリ内のものをリストします。

~/learn $ ls dir1 file1 file2 file3 ~/learn $ ls . dir1 file1 file2 file3 ~/learn $ ls -d . . ~/learn $ ls -dF . ./ ~/learn $ ls ./file1 ./file1 ~/learn $ ls dir1 d1file ~/learn $ ls ./dir1 d1file ~/learn $ pwd /Users/fschmidt/learn ~/learn $ cd . ~/learn $ pwd /Users/fschmidt/learn

.はカレントディレクトリです。

~/learn $ pwd /Users/fschmidt/learn ~/learn $ cd dir1 ~/learn/dir1 $ pwd /Users/fschmidt/learn/dir1 ~/learn/dir1 $ ls . d1file ~/learn/dir1 $ ls .. dir1 file1 file2 file3 ~/learn/dir1 $ cd .. ~/learn $ pwd /Users/fschmidt/learn ~/learn $ cd dir1 ~/learn/dir1 $ pwd /Users/fschmidt/learn/dir1 ~/learn/dir1 $ cd ../.. ~ $ pwd /Users/fschmidt ~ $ cd learn ~/learn $ pwd /Users/fschmidt/learn

..は親ディレクトリです。

~/learn $ echo * dir1 file1 file2 file3 ~/learn $ echo d* dir1 ~/learn $ echo f* file1 file2 file3 ~/learn $ echo *1 dir1 file1 ~/learn $ echo dir1/* dir1/d1file ~/learn $ echo */* dir1/d1file ~/learn $ echo qqq* qqq*

*はファイルのワイルドカードマッチングを行います。重要なのは、バッシュがワイルドカードマッチングを行い、その結果の引数をコマンドに渡すことです。echoは一致がない限り「*」を見ません。

~/learn $ ls * file1 file2 file3 dir1: d1file ~/learn $ ls -dF * dir1/ file1 file2 file3 ~/learn $ ls -dF d* dir1/ ~/learn $ ls -dF f* file1 file2 file3 ~/learn $ ls -dF *1 dir1/ file1 ~/learn $ ls dir1/* dir1/d1file ~/learn $ ls */* dir1/d1file ~/learn $ ls -dF qqq* ls: qqq*: No such file or directory

自明であるべきです。

~/learn $ pwd /Users/fschmidt/learn ~/learn $ cd ~ ~ $ pwd /Users/fschmidt ~ $ cd learn/dir1 ~/learn/dir1 $ pwd /Users/fschmidt/learn/dir1 ~/learn/dir1 $ cd ~ $ pwd /Users/fschmidt ~ $ cd ~/learn ~/learn $ pwd /Users/fschmidt/learn ~/learn $ echo ~ /Users/fschmidt ~/learn $ echo . . ~/learn $ echo .. ..

~はホームディレクトリを意味します。引数なしのcdcd ~と同じです。~はバッシュによってホームディレクトリに展開されます。

~/learn $ ls -ltF total 0 drwxr-xr-x 3 fschmidt staff 96 Jan 5 02:33 dir1/ -rw-r--r-- 1 fschmidt staff 0 Jan 5 02:21 file3 -rw-r--r-- 1 fschmidt staff 0 Jan 5 02:21 file2 -rw-r--r-- 1 fschmidt staff 0 Jan 5 02:21 file1

-lはこの醜い技術的な形式を提供します。ファイルが最後に変更された日付が表示されます。日付の前にはファイルサイズがあります。-tは日付の降順でソートします。

最後にオートコンプリートについて説明します。echo dと入力し、エンター/リターンを押さずにタブキーを押します。これによりecho dir1/にオートコンプリートされます。もう一度タブを押すとecho dir1/d1fileにオートコンプリートされます。ファイルやディレクトリを入力中にタブを押すと、バッシュが一致するファイル名を使用してオートコンプリートを試みます。echo fを入力してタブを押すとecho fileになります。次にどれを選ぶべきか分かりません。もう一度タブを押すとビープ音が鳴ります。そしてもう一度タブを押すと次のようにオプションが表示されます:

~/learn $ echo file file1 file2 file3 ~/learn $ echo file

一般的に、ファイル名を入力中にいつでもタブを押してみてください。オートコンプリートは多くの入力を節約します。

ファイルの操作

目次
~/learn $ ls -F dir1/ file1 file2 file3 ~/learn $ cp file1 copied ~/learn $ ls -F copied dir1/ file1 file2 file3 ~/learn $ mv copied moved ~/learn $ ls -F dir1/ file1 file2 file3 moved ~/learn $ rm moved ~/learn $ ls -F dir1/ file1 file2 file3

cpはファイルやディレクトリをコピーします。mvはファイルやディレクトリを移動します。rmはファイルやディレクトリを削除します。詳細はこれらのコマンドのmanページを参照してください。

~/learn $ ls -F dir1/ file1 file2 file3 ~/learn $ mkdir dir2 ~/learn $ touch dir2/d2file ~/learn $ ls -F dir1/ dir2/ file1 file2 file3 ~/learn $ ls dir2 d2file ~/learn $ rm dir2 rm: dir2: is a directory ~/learn $ rm -d dir2 rm: dir2: Directory not empty ~/learn $ rm dir2/d2file ~/learn $ rm -d dir2 ~/learn $ ls -F dir1/ file1 file2 file3 ~/learn $ ls -F dir1/ file1 file2 file3 ~/learn $ mkdir dir2 ~/learn $ touch dir2/d2file ~/learn $ ls -F dir1/ dir2/ file1 file2 file3 ~/learn $ rm -r dir2 ~/learn $ ls -F dir1/ file1 file2 file3 ~/learn $ ls -F dir1/ file1 file2 file3 ~/learn $ cp dir1 dir2 cp: dir1 is a directory (not copied). ~/learn $ cp -r dir1 dir2 ~/learn $ ls -F dir1/ dir2/ file1 file2 file3 ~/learn $ ls dir2 d1file ~/learn $ cp f* dir2 ~/learn $ ls dir2 d1file file1 file2 file3 ~/learn $ rm -r dir2 ~/learn $ ls -F dir1/ file1 file2 file3 ~/learn $ ls -F dir1/ file1 file2 file3 ~/learn $ mkdir dir2 ~/learn $ cp -r dir1 dir2 ~/learn $ ls -F dir2 dir1/ ~/learn $ ls -F dir2/dir1 d1file ~/learn $ rm -r dir2 ~/learn $ ls -F dir1/ file1 file2 file3

これをすべて説明することもできますが、しません。manを使用してコマンドとそのオプションを理解し、それらを試してみてください。完全に理解するまで続けないでください。

引用

目次
~/learn $ echo a b a b ~/learn $ echo "a b" a b ~/learn $ echo 'a b' a b ~/learn $ echo "a b" c a b c

バッシュは引用符内のテキストを1つの引数として扱います。したがって、echo a bでは、echoには2つの引数があります: "a"と"b"。echo "a b"では、echoには1つの引数があります: "a b"。echo 'a b'では、echoには1つの引数があります: "a b"。echo "a b" cでは、echoには2つの引数があります: "a b"と"c"。

~/learn $ echo a\ \ \ b a b

引用符の外では、\ は区切り文字として扱われず、引数の一部としてスペース文字として扱われます。

~/learn $ echo file* file1 file2 file3 ~/learn $ echo "file*" file* ~/learn $ echo 'file*' file*

引用符はワイルドカード展開を防ぎます。

変数

目次
~/learn $ echo $X ~/learn $ X="some text" ~/learn $ echo $X some text ~/learn $ echo "X is: $X" X is: some text ~/learn $ echo 'X is: $X' X is: $X ~/learn $ X="$X and more" ~/learn $ echo $X some text and more

ここでXは変数です。$Xでその値を取得します。これはダブルクォート内でも機能しますが、シングルクォート内では機能しません。

バッシュで使用される特別な変数を環境変数と呼びます。

~/learn $ echo $PATH /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/fschmidt/Dropbox/bin:/Users/fschmidt/hg/luan/scripts:/usr/local/opt/postgresql@9.5/bin ~/learn $ which ls /bin/ls ~/learn $ cd /bin /bin $ pwd /bin /bin $ ls [\t\tdd\t\tlaunchctl\tpwd\t\ttest bash\t\tdf\t\tlink\trm\t\tunlink cat\t\techo\t\tln\trmdir\t\twait4path chmod\t\ted\t\tls\tsh\tzsh cp\t\texpr\t\tmkdir\tsleep csh\t\thostname\tmv\tstty dash\t\tkill\tpax\tsync date\t\tksh\tps\ttcsh /bin $ ls -F [*\t\tdd*\t\tlaunchctl*\tpwd*\t\ttest* bash*\t\tdf*\t\tlink*\trm*\t\tunlink* cat*\t\techo*\t\tln*\trmdir*\t\twait4path* chmod*\t\ted*\t\tls*\tsh*\tzsh* cp*\t\texpr*\t\tmkdir*\tsleep* csh*\t\thostname*\tmv*\tstty* dash*\t\tkill*\tpax*\tsync* date*\t\tksh*\tps*\ttcsh* /bin $ cd ~/learn ~/learn $

PATHはバッシュがコマンドを検索するディレクトリのリストを:で区切って含む環境変数です。whichコマンドはコマンドへのフルパスを表示します。ls -Fは実行可能ファイルに*を追加します。

~/learn $ subl file1 -bash: subl: command not found ~/learn $ "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl" file1 ~/learn $ PATH="$PATH:/Applications/Sublime Text.app/Contents/SharedSupport/bin" ~/learn $ echo $PATH /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/fschmidt/Dropbox/bin:/Users/fschmidt/hg/luan/scripts:/usr/local/opt/postgresql@9.5/bin:/Applications/Sublime Text.app/Contents/SharedSupport/bin ~/learn $ subl file1 ~/learn $

ここでは、Sublime Textでファイルfile1を編集します。最初はフルパスを使用し、その後ディレクトリをPATHに追加してバッシュがsublを見つけられるようにします。

WindowsでMicrosoft Wordを持っています。Windowsコマンドプロンプト(バッシュではなく)から:

C:\Users\fschmidt>winword C:\Users\fschmidt>where winword C:\Program Files\Microsoft Office\root\Office16\WINWORD.EXE

winwordはMicrosoft Wordを実行します。コマンドプロンプトのwhereコマンドはバッシュのwhichコマンドのようなものです。では、MSYS2で:

~ $ winword bash: winword: command not found ~ $ echo $PATH /usr/local/bin:/usr/bin:/bin:/opt/bin:/c/Windows/System32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0/:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/c/Program Files/TortoiseHg:/c/Program Files/Java/jdk1.8.0_202/bin ~ $ PATH="$PATH:/c/Program Files/Microsoft Office/root/Office16" ~ $ echo $PATH /usr/local/bin:/usr/bin:/bin:/opt/bin:/c/Windows/System32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0/:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/c/Program Files/TortoiseHg:/c/Program Files/Java/jdk1.8.0_202/bin:/c/Program Files/Microsoft Office/root/Office16 ~ $ winword ~ $

Macに戻ると、Finderの「アプリケーション」にあるアプリケーションをコマンドとしてではなくアプリケーションとして実行する別の方法があります。

~/learn $ open -a 'Sublime Text' file1

もう一つの便利な環境変数はPS1で、コマンドプロンプトを制御します。私はすでにこれを設定していますが、もししていなかったら:

Franklins-MacBook-Pro:learn fschmidt$ echo $PS1 \h:\W \u\$ Franklins-MacBook-Pro:learn fschmidt$ PS1="\w $ " ~/learn $ echo $PS1 \w $ ~/learn $

「bash PS1」をGoogleで検索して詳細を確認してください。

.bash_profile

目次
~/learn $ cd ~ $ ls .bash_profile .bash_profile

もし.bash_profileが見つからない場合は、touch .bash_profileを実行して作成してください。このファイルには、バッシュが起動したときに実行されるバッシュコマンドが含まれています。すでにこのファイルがある場合は、#で始まるコメントが含まれている可能性があります。コメントは次のように無視されます:

~ $ # コメント行、何もしません ~ $ echo whatever # 行末コメント whatever ~ $

Macで.bash_profileを編集するには、次を実行できます:

~ $ open -a 'Sublime Text' .bash_profile

Windowsで.bash_profileを編集するには、次を実行できます:

~ $ notepad .bash_profile

次の行を.bash_profileに追加してみてください:

echo hello there

新しいバッシュターミナルを開くと、「hello there」が表示されるはずです。.bash_profileは、新しいバッシュターミナルを開くことでバッシュが開始されたときに実行されます。

私はPS1PATH.bash_profileに設定して、望むコマンドプロンプトとアクセスしたいコマンドを持つようにしています。Sublime TextコマンドsublPATHで利用可能にすることをお勧めします。

「find」コマンド

目次
~/learn $ find . . ./file3 ./file2 ./file1 ./dir1 ./dir1/d1file ~/learn $ find . -name 'file*' ./file3 ./file2 ./file1 ~/learn $ find . -name '*file' ./dir1/d1file ~/learn $ find . -name 'd*' ./dir1 ./dir1/d1file ~/learn $ find . -name '*1' -or -name '*2' ./file2 ./file1 ./dir1

findはディレクトリツリー内のファイルを再帰的に検索します。この場合、*のワイルドカードマッチングはバッシュによって行われているのではなく、findによって行われています。findにはファイルを検索し、それに対してアクションを実行するための多くのオプションがあります。man findを参照してください。

入力と出力

目次
~/learn $ echo 'this is a test' >test.txt ~/learn $ ls -F dir1/ file1 file2 file3 test.txt ~/learn $ cat test.txt this is a test ~/learn $ echo 'this is another test' >test.txt ~/learn $ cat test.txt this is another test ~/learn $ echo 'another line' >>test.txt ~/learn $ cat test.txt this is another test another line ~/learn $ cat <test.txt this is another test another line ~/learn $ cat <<End >test.txt > I am typing this > and this > End ~/learn $ cat test.txt I am typing this and this ~/learn $ (echo one; echo two) >test.txt ~/learn $ cat test.txt one two

すべてのプログラムには標準入力、標準出力、標準エラーがあります。プログラムは通常の出力を標準出力に書き込み、エラーメッセージを標準エラーに書き込みます。デフォルトでは、標準入力はターミナルから来て、標準出力と標準エラーはターミナルに行きますが、これを変更できます。>fileは標準出力をfileに送ります。>>fileは標準出力をfileに追加します。<fileは標準入力をfileから読み込みます。<<whateverwhateverだけの行が来るまで続くテキストから標準入力を読み込みます。コマンドは()の間で組み合わせることができます。catの動作を理解するためにman catを必ず行ってください。

~/learn $ ls >ls.txt ~/learn $ cat ls.txt dir1 file1 file2 file3 ls.txt test.txt ~/learn $ ls -d f* q* >ls.txt ls: q*: No such file or directory ~/learn $ cat ls.txt file1 file2 file3 ~/learn $ ls -d f* q* 2>ls.txt file1 file2 file3 ~/learn $ cat ls.txt ls: q*: No such file or directory ~/learn $ ls -d f* q* | tee ls.txt ls: q*: No such file or directory file1 file2 file3 ~/learn $ cat ls.txt file1 file2 file3 ~/learn $ ls -d f* q* 2>&1 | tee ls.txt ls: q*: No such file or directory file1 file2 file3 ~/learn $ cat ls.txt ls: q*: No such file or directory file1 file2 file3

2>fileは標準エラーをfileに送ります。|は前のコマンドの標準出力を次のコマンドの標準入力に送ります。2>&1は標準エラーを標準出力に送ります。tee fileは標準入力を読み取り、それを標準出力とfileの両方に書き込みます。

~/learn $ find . -type f | wc -l 6

learnには6つのファイルがあります。これがどのように機能するかを理解するためにmanを使用してください。

コントロールキー

目次
~/learn $ sleep 3 ~/learn $ sleep 30 ^C ~/learn $

sleep 3は3秒間スリープします。つまり、3秒間何もしません。このコマンドが終了するのを3秒待ちました。次にsleep 30を実行しましたが、30秒間スリープするはずでしたが、我慢できずにcontrol+cを押してプログラムを中断し、抜け出しました。コマンドが終了するのを待っているときに詰まった場合は、control+cを試してみてください。

~/learn $ wc I am typing this and this now I will end my input with control+d 3 14 65 ~/learn $ wc this time I will use control+c to break out ^C ~/learn $

Control+dは入力の終了を意味します。

コマンド置換

目次
~/learn $ echo I am in $(pwd) I am in /Users/fschmidt/learn ~/learn $ echo this directory contains: $(ls) this directory contains: dir1 file1 file2 file3 ls.txt test.txt ~/learn $ echo this directory contains $(ls | wc -l) files this directory contains 6 files

cmd $(commands)commandsの出力をcmdの引数テキストとして使用します。

~/learn $ cat $(find . -type f) | wc -c 86

learnのファイルには合計86バイトが含まれています。これがどのように機能するかを理解するためにmanを使用してください。

アンパサンド

目次
~/learn $ (sleep 5; echo done) & [1] 10080 ~/learn $ echo waiting waiting ~/learn $ done [1]+ Done ( sleep 5; echo done ) ~/learn $

通常、バッシュはコマンドが完了するのを待ってからコマンドプロンプトを表示し、入力を許可します。しかし、コマンドラインの末尾に&を付けると、バッシュは待たずにコマンドを別のプロセスで実行します。上記の~/learn $ echo waitingでは、echo waitingを入力しました。しかし、~/learn $ doneでは、doneを入力しませんでした。これは5秒後にecho doneによって生成されました。[1] 10080はプロセスが開始されたことを示し、[1]+ Done ( sleep 5; echo done )はプロセスが終了したことを示します。

これは、コマンドが終了するのを待ちたくない場合に便利です。Windowsでは次のように考えてみてください:

~ $ notepad

ここでは、バッシュがこのコマンドの終了を待っているため、ノートパッドを終了するまでコマンドプロンプトを再び取得できません。したがって、代わりに次を行います:

~ $ notepad & [1] 2010 ~ $

これでノートパッドが実行され、バッシュを続けて使用できます。

シェルスクリプト

目次

test.shというファイルを作成し、次の内容を含めます:

echo this is a shell script

次にバッシュから:

~/learn $ cat test.sh echo this is a shell script ~/learn $ ./test.sh -bash: ./test.sh: Permission denied ~/learn $ ls -F test.sh test.sh ~/learn $ chmod +x test.sh ~/learn $ ls -F test.sh test.sh* ~/learn $ ./test.sh this is a shell script ~/learn $

chmod +x filefileを実行可能にして実行できるようにします。次にtest.shを編集します

~/learn $ # edit test.sh ~/learn $ cat test.sh nonsense echo this is a shell script ~/learn $ ./test.sh ./test.sh: line 1: nonsense: command not found this is a shell script ~/learn $ # edit test.sh ~/learn $ cat test.sh set -e nonsense echo this is a shell script ~/learn $ ./test.sh ./test.sh: line 2: nonsense: command not found ~/learn $

デフォルトでは、スクリプトはエラー後も実行を続けます。長いスクリプトでは、エラー後にスクリプトを終了させたいです。set -eはこれを行います。help setを参照してください。

~/learn $ X=some ~/learn $ echo $X some ~/learn $ echo $Xthing ~/learn $ echo ${X}thing something ~/learn $ # edit test.sh ~/learn $ cat test.sh echo "\$* = $*" echo "\$# = $#" echo "\$0 = $0" echo "\$1 = $1" echo "\$2 = $2" echo "\$3 = $3" echo "\$4 = $4" echo "\$14 = $14" echo "\${14} = ${14}" echo "\$@ = $@" ./count.sh "$*" ./count.sh "$@" ~/learn $ ./test.sh a b "c d" $* = a b c d $# = 3 $0 = ./test.sh $1 = a $2 = b $3 = c d $4 = $14 = a4 ${14} = $@ = a b c d 1 3 ~/learn $ cat count.sh echo $# ~/learn $

バッシュスクリプトには特別に定義された変数があります。$*$@の違いは微妙で、通常は$*を使用します。$*はすべての引数を1つの文字列として返し、$@は引数を個別に返しますが、この違いはほとんど影響を与えません。

変数とスクリプト

目次
~/learn $ X=value ~/learn $ echo $X value ~/learn $ # edit test.sh ~/learn $ cat test.sh echo "\$X = $X" ~/learn $ ./test.sh $X = ~/learn $ export X ~/learn $ ./test.sh $X = value

変数は現在のシェルで定義されます。シェルスクリプトは独自のシェルで実行されます。したがって、デフォルトでは、ターミナル/親シェルで定義された変数を参照しません。export varvarを子プロセスで利用可能にします。つまり、シェルスクリプトで利用可能にします。.bash_profileexport PATHを行うことをお勧めします。これにより、PATHがスクリプトで利用可能になります。

~/learn $ X=terminal ~/learn $ echo $X terminal ~/learn $ # edit test.sh ~/learn $ cat test.sh X=script export X ~/learn $ ./test.sh ~/learn $ echo $X terminal ~/learn $ . test.sh ~/learn $ echo $X script

変数を親から子にエクスポートできますが、子から親にはできません。. scriptはファイルscriptのテキストを現在のシェルに含めます。この場合、別のシェルで実行されません。これが、スクリプトがターミナルシェルで変数を設定する唯一の方法です。

~/learn $ pwd /Users/fschmidt/learn ~/learn $ # edit test.sh ~/learn $ cat test.sh cd ~ ~/learn $ ./test.sh ~/learn $ pwd /Users/fschmidt/learn ~/learn $ . test.sh ~ $ pwd /Users/fschmidt ~ $ cd learn ~/learn $

これは./script. scriptの違いを示しています。

あなたのスクリプト

目次
~/learn $ echo $PATH /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/fschmidt/Dropbox/bin:/Users/fschmidt/hg/luan/scripts:/usr/local/opt/postgresql@9.5/bin:/Applications/Sublime Text.app/Contents/SharedSupport/bin ~/learn $ echo ~/Dropbox/bin /Users/fschmidt/Dropbox/bin ~/learn $ ls -F ~/Dropbox/bin/e /Users/fschmidt/Dropbox/bin/e* ~/learn $ cat ~/Dropbox/bin/e open -a 'Sublime Text' $* ~/learn $ e test.sh ~/learn $

便利なスクリプトを書くときは、それらをディレクトリに入れ、そのディレクトリをPATHに追加します。私は~/Dropbox/binを使用しており、そこにeという名前のスクリプトがあります。これにより、コマンドラインからファイルを編集できます。e test.shはコマンドラインからtest.shを編集できます。

バッシュはスクリプトを探すときに、明示的なパスを指定しない限り、PATH内のスクリプトのみを探します。

~/learn $ # edit test.sh ~/learn $ cat test.sh echo this is a shell script ~/learn $ test.sh -bash: test.sh: command not found ~/learn $ ./test.sh this is a shell script ~/learn $

test.shを単独で呼び出すと失敗します。これはPATHにないためです。しかし、./test.shは明示的なパスであるため機能します。

高度なスクリプト

目次

ここにWord DOCXファイルを解凍するundocx.shというより高度なスクリプトがあります。

#!/bin/bash set -e if [ $# -ne 1 ]; then echo "usage: $0 filename" exit 1 fi FILE="$1" NEWDIR=$(basename $FILE .docx) mkdir $NEWDIR unzip $FILE -d $NEWDIR export XMLLINT_INDENT=$'\t' for file in $(find $NEWDIR -name "*.xml" -o -name "*.rels"); do mv "$file" temp.xml xmllint --format temp.xml >"$file" done rm temp.xml

バッシュは通常の機能を含む完全なプログラミング言語です。私のスクリプトのいくつかのコマンドはmanでよく説明されていますが、いくつかはそうではありません。特にifforのドキュメントは不十分です。このような場合、ChatGPTに次のように尋ねることをお勧めします:

Please explain the Bash "if" statement. Please explain the Bash "for" statement.

ChatGPTはバッシュをよく知っています。ChatGPTに詳細を説明してもらうことを信頼していますが、コアコンセプトを説明することは信頼していません。Googleを試すこともできますが、ChatGPTは現代のプログラマーよりも優れています。

結論

目次

バッシュの使用の少なくとも90%は、ターミナルに入力する単純なコマンドです。できるだけバッシュを使用し、GUIを使用する代わりにバッシュを使用して練習してください。システム管理者にならない限り、高度なスクリプトをあまり使用しません。しかし、コアの基本をしっかりと理解していれば、必要に応じて高度なスクリプトを読み書きする方法を理解できるはずです。