汎用コマンド
ssh
リモート先のファイルの存在チェック
REMOTE_FILE="foo.txt"
if ssh localhost "[[ -e ${REMOTE_FILE} ]]" ; then
echo "ファイルあり"
else
echo "ファイルなし"
fi
grep
終了ステータス
該当行が見つからないときは終了ステータスが1になります。set -e
でエラーがあったら止まる状態にしている場合は、注意が必要です。
find
ファイル名だけ表示
$ find . -printf "%f\n"
xargs
Man page of XARGS
xargsコマンドで覚えておきたい使い方・組み合わせ7個(+1個)
xargsのオプション無し、-Iオプション、-0オプションの挙動に関する勘違い
デリミタを改行にする
findコマンドで見つかったファイルが半角スペースを含む場合は、xargsコマンドのデリミタを改行にする必要があります。
$ find . -name "*.txt" | xargs -d "\n"
NULL文字を区切りにして対応することもできます。
$ find . -type f -print0 | xargs --null md5sum
個別のファイルにリダイレクト
-
sh -c
:で引数に渡された文字列を、コマンドを実行する -
xargs -t
: 実行する前に、コマンドラインを標準エラー出力に表示する。
$ ls *.png
a.png b.png c.png
$ find . -name "*.png" | xargs -t -I{} sh -c "identify -verbose {} > {}.identify"
sh -c identify -verbose ./a.png > ./a.png.identify
sh -c identify -verbose ./b.png > ./b.png.identify
sh -c identify -verbose ./c.png > ./c.png.identify
$ ls *.identify
a.png.identify b.png.identify c.png.identify
改行コードを入れてファイルを連結する
1行1ファイルのJOSN(改行コードなし)を連結して、JSON Linesを生成する。
$ find -type f -name "*.json" | xargs -I{} sh -c "cat {}; echo ''" > ../lines.json
find
対象のプロジェクトにlines.json
を出力すると、「入力ファイルと出力ファイルが同じです」という警告が出る。
応用:grepで抽出したファイルを削除する
$ find . -type f -name "*.json" -print0 | xargs -0 grep --files-with-matches 'foo' | xargs rm
ls
ディレクトリ内のファイル数をカウント
$ ls -U1 | wc -l
-U
でソートしなくなるので、速くなる。
https://qiita.com/stc1988/items/e3a1d7dccafe4ab573fa
date
dateコマンドの1か月前や1か月後は30日で計算しているだけ
# 2020-03-31の1か月後は2020-04
$ date --date "2020-03-30 1 month" +%Y-%m
2020-04
# 2020-03-31の1か月後は2020-05?
$ date --date "2020-03-31 1 month" +%Y-%m
2020-05
diff
ディレクトリ構成のみの比較(ファイルの中身は比較しない)
$ diff <(ls -1 dir1) <(ls -1 dir2)
rsync
ssh経由でリモート先にコピー
# `ssh remotehost`で接続できるよう、あらかじめ`.ssh/config`に設定してある状態
$ rsync -auv -e "ssh" src remotehost:~/dest
-
-u
: 転送先に既にファイルが存在し、転送先のタイムスタンプの方が新しい場合は転送しない -
-v
: 詳細情報を表示
tmux
プロンプトの色が表示されるようにする
tmuxを利用しているときも、プロンプトに色(環境変数PS1
の設定)を付けるため、.bashrc
のforce_color_prompt=yes
部分のコメントを外す。
履歴の上限を増加する
set -g history-limit 10000
rename
再帰的にファイル名の先頭にprefix-
を付ける
$ find . -name "*.csv" | xargs rename 's/([^\/]*)$/prefix-$1/'
sed
特定のキーワードを見つけた行から、末尾までを削除する
AAA
BBB
CCC
DDD
$ sed "/BBB/q" foo.txt | sed -e '$d'
システム管理系のコマンド
crontab
crontabで実行するスクリプトでは、bashrcを読み込まない方がよい
対話的なシェルでないと、bashrcの読み込み途中でreturnされてしまうため
https://qiita.com/takaram/items/17e739e9b7d4d7b6de42
パーセント記号はエスケープする
# 動かない
# 00 04 * * * TODAY=$(date "+%Y-%m-%d"); echo ${TODAY} > ~/log/${TODAY}.txt 2>&1
# 動く
00 04 * * * TODAY=$(date "+\%Y-\%m-\%d"); echo ${TODAY} > ~/log/${TODAY}.txt 2>&1
cronの実行ログはjournalctlコマンドで確認する
sudo journalctl --follow --unit cron
-- Logs begin at Thu 2019-05-30 11:01:44 JST. --
...snip
6月 22 23:03:01 pinkumohikan.com CRON[2080]: (pinkumohikan) CMD (echo 1)
...snip
crontabのデフォルトシェルはshなので、sourceコマンドは使えない
ssh
-
-i
:秘密鍵のファイルを指定 -
-Y
: X11 ForwardingでGUI操作(Enables trusted X11 forwarding.)
秘密鍵を指定したときに「Permissions ... are too open」というエラーが発生
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0664 for '.ssh/keypair.pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key ".ssh/keypair.pem": bad permissions
chmod 600 ~/.ssh/keypair.pem
コマンドを実行して、パーミッションを変更しました。
http://yachibit.hatenablog.jp/entry/2013/04/25/001912
ssh -Y
コマンドでX11 forwarding request failed on channel 0
が発生
xauthが必要
https://qiita.com/mohi_teak/items/473fda1f03cbd9cc8518
du
今いるディレクトリの容量
$ du -sh ./*/
ピリオドから始まるディレクトリの容量も算出
$ du --block-size=1M --summarize * .[^\.]* | sort --numeric-sort --reverse
mount
ディレクトリに別ディレクトリをマウント
# mount --bind old_directory new_directory
pkill
たくさん開かれている画像ビューアristretto
を、まとめて落とす。
$ # ristretto を終了させる
$ pkill -f ristretto
$ pkill -f gpicview
$ # thunar を終了させる. usernameを指定
$ pkill -f Thunar -u yuji38kwmt
Bash
変数関係
-
$_
: 直前のコマンドの最後の引数(mkdir sample && cd $_
)
http://www.go-next.co.jp/blog/server_network/os/18616/ -
-
: 標準入出力(cat -
)
https://www.softel.co.jp/blogs/tech/archives/2151/comment-page-1
変数内に改行を含む場合
改行した状態で出力する場合、変数を二重引用符で括ります。
FOO="a
b"
echo ${FOO}
echo "${FOO}"
$ ./foo.sh
a b
a
b
その他
ターミナル上でキー入力を受け付けなくなった場合
実行スクリプトの存在するディレクトリに移動する
SCRIPT_DIR=$(cd $(dirname $0); pwd)
pushd ${SCRIPT_DIR}
popd
https://qiita.com/koara-local/items/2d67c0964188bba39e29 参照
よく使うbashオプション
#!/bin/bash -euvx
https://qiita.com/dskshmz/items/c01f29f8398cc7f5c396 参考
「引数リストが長すぎる」というエラー
$ # カレントディレクトリには、10万件以上の"jpg"ファイルが存在する
$ mogrify -path ../test2 -resize 128x *.jpg
bash: /usr/bin/mogrify: 引数リストが長すぎます
$ # echoとxargsで解決
$ echo ./*.jpg | xargs mogrify -path ../test2 -resize 128x
10進数に変換
$ echo $(( 008 + 1 ))
bash: 008: 基底の値が大きすぎます (エラーのあるトークンは "008")
$ echo $(( 10#008 + 1 ))
9
コマンドライン引数の解析
#!/bin/bash -e
PROGNAME=$(basename $0)
usage_exit() {
echo -ne "Usage: ${PROGNAME} --project_id PROJECT_ID [--account_id ACCOUNT_ID] [--delete] [--help] \n" 1>&2
exit 1
}
FLAG_DELETE=false
PROJECT_ID=""
ACCOUNT_ID=""
if [ $# -gt 0 ]; then
for OPT in "$@"
do
case ${OPT} in
"-p" | "--project_id")
if [ -z "$2" ]; then
echo "${PROGNAME}: ${1} オプションには値を設定してください" 1>&2
exit 1
fi
PROJECT_ID=$2
shift 2
;;
"-a" | "--account_id")
if [ -z "$2" ]; then
echo "${PROGNAME}: ${1} オプションには値を設定してください" 1>&2
exit 1
fi
ACCOUNT_ID=$2
shift 2
;;
"--delete")
FLAG_DELETE=true
shift 1
;;
"-h" | "--help")
usage_exit
;;
-*)
# 無効なオプションを判定
echo "${PROGNAME}: illegal option $1" 1>&2
exit 1
;;
*)
# 無効なパラメータを判定
if [ -n "$1" ] && [[ ! "$1" =~ ^-+ ]]; then
echo "${PROGNAME}: illegal parameter $1" 1>&2
exit 1
fi
;;
esac
done
fi
if [ -z "${PROJECT_ID}" ]; then
echo "--project_id は必須" 1>&2
usage_exit
fi
echo '処理開始'
echo "PROJECT_ID = ${PROJECT_ID}"
echo "ACCOUNT_ID = ${ACCOUNT_ID}"
echo "FLAG_DELETE = ${FLAG_DELETE}"
https://qiita.com/b4b4r07/items/dcd6be0bb9c9185475bb 参照
.bashrc
関係
コマンド履歴の前方探索をCtrl+Sで行う
stty stop undef
stty start undef
https://qiita.com/sasaplus1/items/be55798643ea02179e65
https://linuxfan.info/disable-ctrl-s
履歴の上限を増やす
複数端末間でコマンド履歴(history)を共有
プロンプトの表示を変更
プロンプトが長すぎる場合などは、設定する
https://qiita.com/katsukii/items/da37d1fdf974bd0e4c2f
適切なaliasを設定
alias rm='rm -i'
Gitブランチ名を表示
git-prompt.shをダウンロードして、以下の設定を行う。
source ~/.git-prompt.sh
# ホスト名とユーザ名を緑色、作業ディレクトリを青色、ブランチ名を紫色 で表示
PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\[\033[01;35m\]$(__git_ps1 " (%s)")\[\033[00m\]\$ '