up:: Programming

総合
Bashの便利な構文だがよく忘れてしまうものの備忘録 - Qiita

[

コマンド]は引数。
test文と同じく条件を評価する。

Bashの括弧のノウハウ(まとめ) - Qiita

ls

ディレクトリ内のファイルを表示する。
-Fを使うことでファイルとディレクトリを見分けられるようになる。
lsコマンドの使い方と覚えたい15のオプション【Linuxコマンド集】
ls command output to variable in script

echoで標準入力

サブシェル起動してcat。

echo コマンドで標準入力を受け取る - Qiita

if

角かっこを使い条件式、thenとfiがいることだけ注意
条件式はコマンドオプションで表現する
ファイル・ディレクトリの見分けもつけられる

シェルスクリプトのif文まるわかり!条件分岐のすべて | IT・ものづくりエンジニアの転職・派遣求人情報なら【パソナテック】
linux - Check if argument is a file or directory - Stack Overflow

ファイル名一括変換

lsからsedしてmvでいける。
なお一番楽なのはrenameを使うこと。gitbashにはいないけど。

他にもfordodoneで回す方法もある。

Linuxでファイル名の一括変換を行う方法: 小粋空間

空白のある名前を扱う場合は、""で括ってmvコマンドに入れるときだけ適切に展開させる。

linux - mv a file that contains spaces from a shell script - Stack Overflow

変数展開

shellscriptにも当然変数があるのだが、実は変数の開き方がいっぱいある。
ググりにくいので多用は禁物。
また、正規表現は使えない。やりたいならechoしてsedに渡す。

【シェル芸人への道】Bashの変数展開と真摯に向き合う - Qiita
bashで変数を正規表現で置換して変数に代入する方法: 小粋空間

sed

文字列置換。\dといったメタ文字は使えない。
使いたいなら[0-9]などで代用する。

sedの正規表現で「\w」「\d」「\s」を実現する方法: 小粋空間

スクリプトの置かれてる場所を拾う

シェルスクリプトが置かれている絶対パスを取得する. スクリプトの配置場所を意識しないですむので便利。 | ITを使っていこう

../../Info/Shebang

標準入出力の繋ぎ変えとパイプ

出力

bashでは入出力に数字が振られている。

ファイル・ディスクリプター番号出力先
0標準入力
1標準出力
2標準エラー出力
n任意の入出力先

(ディスクリプタは出力先の意)
出力先を変更することを 出力のリダイレクト という。
この出力先をファイルに指定すると、出力結果を記したファイルが作れる。
ディスクリプタ番号と>で指定する。

echo "Hello" 1> file1
#標準出力をfile1に書き出す。
#この場合「Hello」と書かれたfile1が生成される。
 
basename 2> file2
#標準エラー出力をfile2に書き出す。
#この場合以下が出力される。
 
#basename: missing operand
#Try 'basename --help' for more information.

数字をつけないと「1」をつけたのと同じ扱いになる。

追記

>の代わりに>>を使うと追記となる。
ちょっとひねったものとして、1>2>>を続けて書くことで標準出力と標準エラー出力を同じファイルに出力できる。

複製

出力番号、>、 & 、出力先番号 でその時点での出力先番号に設定されている出力先を複製して設定する。出口を出力先にくっつける。この書き方なのに出力の変更が入力に反映される形になっているので注意。

aa > file1 2>&1
cat file1
 
#./test.sh: line 1: aa: command not found

2>&1を呼び出した時点で、1番に設定されているのはfile1。
なので2番の出力先に標準出力が複製されて設定される。

ディスクリプタ出力先(当初)1> file1 適用後2>&1適用後
1標準出力(ターミナル)file1file1
2標準エラー出力(ターミナル)標準エラー出力(ターミナル)file1

そのため、文の順番を逆にすると意味が変わる。

aa 2>&1 >file1
cat file1
 
#
ディスクリプタ出力先(当初)2>&1適用後1> file1 適用後
1標準出力(ターミナル)標準出力(ターミナル)file1
2標準エラー出力(ターミナル)標準出力(ターミナル)標準出力(ターミナル)

bash: 標準出力、標準エラー出力をファイル、画面それぞれに出力する方法 - Qiita
用語集:リダイレクト: UNIX/Linuxの部屋

>&と&>

ややこしいとこ。正しいのは >&。
例えばecho '7' 2&>1&>が別々に解釈され、echoに2という引数を渡すことになる。当然2というファイルは存在しないため、echoは標準エラー出力(2)にエラーを吐く。それを1というファイルに出力するという意味になってしまう。

……この言い方だと&が余るのだが。
ちなみに、コマンド末尾に&をくっつけるとバックグラウンドで実行される。
でもここでは真ん中に&があるわけで……よくわからない。

>&と&>、古い情報
リダイレクトとして 2&>1 を使うと何が起きるのか? - Qiita
Linuxコマンド(Bash)でバックグラウンド実行する方法のまとめメモ - Qiita

/dev/null

/dev/null を繋ぐことで出力を破棄したり新規ファイルを作ったりファイルの中身を消したりできる。
まあ後ろ二つは普通に上書きすればいいんだけど。
エラー抑制には役立つかも。

myscript.sh >/dev/null 2>&1   # 標準出力と標準エラー出力を破棄する (crontable でよく用いられる使い方)
somecommand 2>/dev/null        # エラー出力だけ破棄する
cat /dev/null > myfile.txt     # サイズ0のファイルを作る
cp /dev/null > myfile.log      # (参考)既存のファイルのサイズを0にする(新規であれば上の例に同じ新規作成)

余談。powershellで同じようなことをしたい場合は、変数$nullに投げるか、パイプでOut-Nullに入れるか。

PowerShell/PowerShellで/dev/null - Windowsと暮らす

パイプ

パイプ|は前者のコマンドの標準出力を後者の標準入力に設定する。
だからといってまんまコマンド 0>&1 コマンドで代用はできない。
|&1と2を両方コマンドに出力できる。


入力

>で出力できるということは、当然<で入力できる。
同様に 入力のリダイレクト と呼ぶ。

mysql -h mydbhost.intranet -u myuser -p mydatabase < sqlfile.sql

一部のコマンドにしか効かない。試したけどechoは無理だった。

ヒアドキュメント

こちらの<<ヒアドキュメント を作る。
英語だとhere-document。

#!/bin/sh
 
NOW\=\`date "+%Y/%m/%d %H:%M:%S"\`
 
cat <<EOF
Now is $NOW
EOF
 
cat <<'EOF'
Now is $NOW
EOF
 
cat <<"EOF"
Now is $NOW
EOF

文字通り「スクリプト上にドキュメントを作る」機能。
この場合EOF~EOF間を「そう書かれたドキュメント」として受け取る。
なお、EOFは任意の文字列なのでPUIPUIとかでもいい。

ここでEOF横に出力をくっつけると、ヒアドキュメントを直接ファイルに出力できる。

cat << EOF > filename.txt
Now is $NOW
EOF

派生で<<-EOFとすると頭のタブ文字を消せる。(可読性向上)

#!/bin/sh
 
NOW\=\`date "+%Y/%m/%d %H:%M:%S"\`
 
cat <<-EOF
	Now is $NOW
EOF

なおこれで消せるのは\t、ハードタブと言われるもののみ。
スペース4つとかは消せないので使うかと言われると……。

ヒアストリング

<<<で文字列を渡せる。

cat <<< "May the force be with you."

sh/bashのパイプ/リダイレクションの使い方 - dec9ue’s diary
覚えてると案外便利なBashのリダイレクト・パイプの使い方9個 | 俺的備忘録 〜なんかいろいろ〜

man bash

マニュアルを出せる。

echo

入力したテキストを標準出力してくれるコマンド。

-e

エスケープ文字を開いてくれる。

クォーテーション

  • シングル
    全て文字列になる。
  • ダブル
    変数を展開する。
    言い換えると、変数名を変数に置換する。
  • バッククォート
    コマンドとみなし、実行結果と置換する。

—help

ヘルプが読める……筈だが、termuxだと普通に出力された。
pkgでmanをインストールし、man echoで出力した。
echoコマンドの詳細まとめました【Linuxコマンド集】

export

環境変数を設定できるコマンド。
普通は変数は全部大文字。

export SAMURAI="samurai engineer"などとすることで動く。

確認

printenv
printenv |grep SAMURAIなどとすると狙った部分だけ出せる。

消去

export -n SAMURAI

【Linuxコマンド】exportで環境変数を設定する方法 | 侍エンジニアブログ

$1

引数が入っている変数。2以降も同じ。
$0はそのコマンドが入っている場所が入っている。

dirname

パス名からディレクトリを取得。

ln

ln target path
シンボリックリンクなどを作るコマンド。targetのものをpathに転写する。
cmdのmklinkと逆。

targetのフォルダーをpathにその末尾の名前でリンクファイルとして作るので、pathに同名のファイルかフォルダーがあるとめんどくさいことになる。

-sでシンボリックリンクになる。