コメントは#の右側に書く。
# ここはコメント echo "Hello, world!!" # ここもコメント
$ cd ~ $ mkdir tools
bashを使っておれば、シェルが起動したときに実行される~/.bashrcという設定ファイルがある。これに、以下の文を追加する。家のパソコンでは文末に追加した。
if [ -d $HOME/tools ] then PATH=$PATH:$HOME/tools; export PATH fi
これでどんなディレクトリにいても、toolsディレクトリに置いたシェルスクリプトのファイル名を打つだけで、実行ができる。まるで、コマンドのよう。むしろコマンドなのかな?
注)シェルスクリプトのパーミッションを以下のように実行可能にしておく。さもなくば、動かない。
$ cd ~/tools $ chmod u+x シェルスクリプト名
$ echo $PATH /home/username/tools:/usr/local/bin:/usr/bin:/bin
これらは、リダイレクトを行うコマンドである。リダイレクトとは、シェルの入出力先を変更することであり、変更先は主にファイルとなる。
コマンドの出力をファイルに上書き保存する。元々output_1というファイルがあった場合、その内容は消され、新たに上書きされる。逆に、output_1というファイルがなかった場合、新たにファイルが作られる。
$ ls -la > output_1
ファイル名: output_1 |
---|
total 47585 drwx------+ 7 user なし 0 Jan 24 19:06 . drwx------+ 3 user なし 0 Dec 20 21:27 .. -rw------- 1 user なし 172 Jan 23 23:49 .bash_history drwxr-xr-x+ 3 user なし 0 Dec 24 04:01 .emacs.d -rw-r--r-- 1 user なし 0 Jan 24 19:06 output_1 |
コマンドの出力をファイルに追記保存する。元々output_2というファイルがあった場合、その内容は残り、最後尾に追記保存される。逆に、output_2というファイルがなかった場合、新たにファイルが作られる。
$ echo "test str1" >> output_2 $ echo "test str2" >> output_2 $ echo "test str3" >> output_2
ファイル名: output_2 |
---|
test str1 test str2 test str3 |
コマンドの入力をファイルから行う。以下の例では、output_2というファイルの内容を読み込み、端末に表示する。
$ cat < output_2 test str1 test str2 test str3
ファイル名: output_2 |
---|
test str1 test str2 test str3 |
この二つのコマンドは、入出力に関するコマンドである。>>, >, <と違い、ファイルから入力したり、ファイルへ出力したりしない。
このコマンドはパイプを実現する。すなわち、あるコマンドの出力を別のコマンドの入力にするときに、このコマンドを使う。以下の例では、ls -laコマンドの出力する内容から、"out"という文字列が含まれる行を探し、表示する。
$ ls -la | grep out -rw-r--r-- 1 user なし 0 Jan 24 19:06 output_1
複数行にわたる内容をコマンドの入力にする。以下の例では、複数行にわたる文字列をcatコマンドの入力とし、その内容を表示する。
$ cat << EOT # EOTと入力されるまでがcatコマンドの入力となる。EOTは他の文字列でも良い。 > test str1 > test str2 > test str3 > EOT test str1 test str2 test str3
EOTを' 'で囲むと変数が展開されなくなる。
$ cat << 'EOT' > test $str1 > test $str2 > EOT test $str1 test $str2
シェルスクリプトでは、変数を宣言なしに使える。変数は文字列のみを格納し、数値も文字列として解釈される?
文字列を変数に代入し、その内容を表示する。
$ para1="aa" $ para2='bb' $ para3=cc $ echo $para1 $para2 $para3 aa bb cc $ echo ${para1} ${para2} ${para3} # こう書いても良い。むしろこっちのほうが応用が利く? aa bb cc $ echo "${para1}" '${para2}' # ちなみに"と'の解釈の違い。 aa ${para2}
"や'を変数に代入し、その内容を表示する。
$ para1="aa'aa" $ para2='bb"bb' $ echo $para1 $para2 aa'aa bb"bb
変数を解釈し、他の変数に代入する。
$ para1="aa" $ para2="bb${para1}bb" $ para3='bb${para1}bb' $ para4=bb${para1}bb $ echo $para1 $para2 $para3 $para4 aa bbaabb bb${para1}bb bbaabb
エラー/いろんな書き方
$ para1 = "aa" # エラー。"="の左右にはスペースを入れてはいけない。 bash: para: command not found $ para1="aa" $ para2="bb$para1bb" # 思い通りにいかない。(文字列"bbaabb"は代入されない。) aa bb $ para1="aa" $ para2="bb" # 以下echoの出力に関するテスト。 $ echo $para1$para2 aabb $ echo "$para1""$para2" aabb $ echo $para1 $para2 aa bb $ echo "$para1" "$para2" aa bb $ echo $para1 $para2 aa bb $ echo "$para1" "$para2" aa bb
書式は以下のとおり。
if [ 条件式1 ] then コマンド1a コマンド1b elif [ 条件式2 ] then コマンド2a コマンド2b else コマンド3a コマンド3b fi
条件式1が真ならば、コマンド1a, コマンド1bのみが実行され、条件式2の真偽にかかわらず、他のコマンドは実行されない。条件式1が偽で、条件式2が真ならば、コマンド2a, コマンド2bのみが実行される。条件式1、条件式2がともに偽ならば、コマンド3a, コマンド3bのみが実行される。
メモ1) elifや、elseの部分は書かなくてもよい?また、elifの部分はたくさん書いてもよいかも?
メモ2) 条件式の返す値(?)は、0とか1じゃないかも?下記の例はともにtrueになる。
$ if [ 1 ] >then > echo "true" >else > echo "false" >fi true
$ if [ 0 ] >then > echo "true" >else > echo "false" >fi true
case 変数 in パターン1 ) コマンド1a ; コマンド1b ;; パターン2 ) コマンド2a ; コマンド2b ;; ..... パターンn ) コマンドna ; コマンドnb ;; * ) コマンド*a ; コマンド*b ;; esac
変数の値がパターン1に一致するときは、コマンド1a, コマンド1bのみが実行され、他のコマンドは実行されない。変数の値がパターン1に一致せず、かつパターン2に一致するときは、コマンド2a, コマンド2bのみが実行され、他のコマンドは実行されない。変数の値がパターン1〜パターンnに一致しないときに限り、コマンド*a, コマンド*bが実行される。パターンには正規表現も可。* )の行は書かなくてもよい。case文はif文を用いて同じことが出来そう。すなわち、if文があれば、case文は必要ないかも?
また、以下のように書いても、エラーにならない。
case 変数 in パターン1 ) コマンド1a コマンド1b; コマンド1c; コマンド1e; コマンド1f コマンド1g コマンド1h; ;; パターン2 ) コマンド2a; コマンド2b コマンド2c ;; esac
以下のとおり。
$ echo $SHELL
以下のとおり。
$ finger username Login: username Name: username Directory: /home/username Shell: /bin/bash
ちなみに現在のユーザーを調べるには、以下のようなコマンドを打つ。
$ echo $USER
以下のコマンドを打つ。ログイン時適用?
$ chsh username Password: userのパスワードを入力 kobaのログインシェルを変更中 新しい値を入力してください, 標準設定値を利用するには リターンを押してください. ログイン・シェル [/bin/bash]: /bin/csh ← cshに変更
管理者の設定により無理な場合があるらしい。
例えば、シェルスクリプト中に以下のようにcdコマンドを書き、そのシェルスクリプトをホームディレクトリ以外で実行すると、cdは実行されずホームディレクトリに移動しないように見える。
ファイル名: smp1.sh |
---|
#!/bin/bash cd ~/ |
これは、シェルスクリプトを実行したシェル(カレントシェル)が、子プロセスとしてもう一つシェル(サブシェル)を走らせ、そこでシェルスクリプトを実行するためである。すなわち、一度cdは実行されるものの、シェルスクリプトの実行が終われば、子プロセスが終了し、元のディレクトリに戻ってしまう。
これは、以下のシェルスクリプトを実行すれば、確認できる。ただし、pwd(print working directory)はカレントディレクトリを表示するコマンド。
ファイル名: smp2.sh |
---|
#!/bin/bash pwd cd ~/ pwd |
カレントシェルでシェルスクリプトを実行するには、ドットコマンド . を用いる。例えば、上記のシェルスクリプト(ファイル名: smp2.sh)を実行すると、実行結果は以下のようになる。
username@hostname:~/dir1/dir2/dir3$ . smp2.sh # . smp2.sh は、. ./smp2.sh と書いてもよい。 /home/username/dir1/dir2/dir3 /home/username username@hostname:~$
書体 | 意味 | 例 |
---|---|---|
AaBbCc123 | 端末の表示する文字。またはコードなど。 | $ You have mail. |
AaBbCc123 | ユーザーが入力する文字。 端末の表示する文字と区別する。 | $ su password: |
AaBbCc123 | コマンドの引数やコードの可変部分。 実際の名前や値と置き換える。 | $ rm filename |