http://qiita.com/jpshadowapps/items/d6f9b55026637519347f
自分用にメモしておく
コマンド実行
CMD1; CMD2
, CMD1 && CMD2
;
はCMD1
の結果に関わらずCMD2
も実行される&&
はCMD1
の結果が正常な場合のみCMD2
が実行される
CMD1 || CMD2
– 失敗時に後続コマンドを実行する
CMD || printf "%b" "MSG"
でエラーメッセージを表示する- エラーメッセージ表示後
exit 1
したい場合 =CMD || { printf "%b" "FAILED.\n" ; exit 1 }
CMD || printf "%b" "FAILED.\n" ; exit 1
と波括弧無しで書くと期待通り動作しない(CMDが成功時もexit 1
してしまう)
- エラーメッセージ表示後
CMD &
– バックグラウンド実行
CMD &
で[1] 4592
のようにジョブ番号とプロセスIDが表示される- killしたければ
kill %ジョブ番号
かkill プロセスID
する - フォワグラウンド実行に戻したければ
- killしたければ
$!
で、直前にバックグラウンド実行したジョブのプロセスIDを取得可能- さらに
wait ${PID}
で待つと、バックグラウンドジョブが終了するまで待つことが出来る
# バックグラウンドで実行したhubotの終了を待つ例
./bin/hubot -a ${HUBOT_ADAPTER} --name ${HUBOT_IRC_NICK} 2>&1 &
HUBOT_PID=$! # PIDを取得
wait ${HUBOT_PID} # ここで終了まで待つ
RET=$? # wait直後の $? で、バックグラウンドジョブの終了コードを取得できる
echo "Hubot is end. PID: ${HUBOT_PID}"
$(CMD)
– サブシェルでコマンド実行、実行結果は$()
に置換される
- 結果の改行はスペースに置換される
$IFS
変数によって決まる(これのデフォルトがスペース)
nohup CMD &
– 実行中のバックグラウンドジョブの継続
- シェルを終了してもコマンドを継続したい場合につける
- 付けずにシェルを終了すると(シェルの子プロセスである)バックグラウンドジョブには SIGHUP が送られ終了する
$?
– コマンドの戻り値
- 直前のコマンドの戻り値判定は2重括弧を使って
if (( $? ))
と書ける
type
, which
, locate
, apropos
コマンドやマニュアルを探す
file
, stat
– ファイルの情報を表示
ドキュメンテーション
: DOCUMENT
– 組み込みドキュメント
: <<'EOD' ... EOD
ハイフンのtips
CMD - ...
ハイフンで標準入(出)力を受け取る/出力する
- 【linux】コマンドの引数を標準入力から渡す at softelメモ
- 「なんだよ、ファイルしか受け付けないのかよ」と思われる場合でも、ハイフンを指定すると、標準入出力への入出力が可能
- dockerの公式インストールチュートリアルにある
wget -qO- https://get.docker.com/ | sh
とかもこのパターン-O <ファイル名>
のところを-
とすることで標準出力に出して、それをそのままパイプで後続コマンドに繋げている
CMD -- ...
ハイフン2つ = それ以降をコマンドラインオプションとは解釈しなくなる
- 例えばハイフン付き文字列そのものをgrepしたいときは
grep -- "-hoge" *
のようにする - これはコマンドオプションの構文解析に使われている
getopt()
の機能で、getopt()
はコマンドオプションに–を見つけるとオプションの解析を終了する - 最近良く見る
curl http://hoge.com/huga.sh | sh
形式のcurl→shインストールで、スクリプトオプションを指定したい時にも使えるcurl -sSf https://static.rust-lang.org/rustup.sh | sh -s -- -y
– rustup.sh に-y
オプションを渡して実行-s
で標準入力からの受け取りを指定--
で それ以降をただの入力文字列と解釈させる-y
をオプションとして入力させる
変数
シェルで「変数がセットされていない」とはどういうケースか?
""
空文字- 明示的に
unset VAR
された変数
$*
と$@
の空白を含んだ引数の取り扱いの違い
./hoge.sh *.txt
と実行した場合for FN in "$*"
は"aaa.txt bbb ccc.txt ddd.txt"
を受け取るのに対し、for FN in "$@"
は"aaa.txt" "bbb ccc.txt" "ddd.txt"
を受け取る
${:-}
– 変数未指定時にデフォルト値を使う
FILEDIR=${1:-"/tmp"}
– 第1引数が “未指定” なら “/tmp”をデフォルト値として利用する- デフォルト値を取得・利用はするが、アサインはしない。
${VAR:-"hoge"}
はVAR
に”hoge” をセットするわけではない
${:+}
– 変数指定時にデフォルト値を使う
FILEDIR=${VAR:+"/tmp"}
–VAR
が設定されていたら “/tmp”を(代わりに)利用する
${VAR:=}
– 変数未指定時にデフォルト値を設定
cd ${HOME:=/tmp}
–${HOME}
が “未指定” なら、代わりにデフォルト値をセット- “未指定” とはどういうケースか? =
""
空文字 もしくはunset
されている ケース
- “未指定” とはどういうケースか? =
- デフォルト値を取得・利用し、変数へのアサインも行う。
${VAR:="hoge"}
はVAR
に”hoge” をセットする
${VAR=}
– 変数未指定時にデフォルト値を設定, :
無し
- とにかく
${VAR:=}
と混同しやすいが、こちらの “未指定” はunset
されている ケースのみが対象で、空文字は対象外
${VAR:?"MSG"}
– 変数がセットされていない場合、メッセージを出力してexitする
USAGE="usage: myscript scratchdir sourcefile conversion"
FILEDIR=${1:?"Error. You must supply a scratch directory."}
FILESRC=${2:?"Error. You must supply a source file."}
CVTTYPE=${3:?"Error. ${USAGE}"}
$ ./myscript /tmp /dev/null
./myscript: line 5: 3: Error. usage: myscript scracthdir sourcefile conversion
# エラー時にコマンドを動かしたければこう書ける
CVTTYPE=${3:?"Error. $USAGE. $(rm $SCRATCHFILE)"}
# ./myscript: line 5: 3: Error. usage: myscript scracthdir sourcefile conversion
# でもこっちの方がコードの可読性は高いね。商用コードならこうすべきだね
# ただしエラーメッセージにファイル名・行番号は出力されないけどね
# ${3:?} はデバッグ時には便利だけどね
if [ -z "$3" ]
then
echo "Error. $USAGE"
rm $SCRATCHFILE
fi
変換
name:number:number - 部分文字列取得
#name - 文字列の長さ
name#pattern - 文字列前方のpatternを削除(最短マッチ)
name##pattern - 文字列前方のpatternを削除(最長マッチ)
name%pattern - 文字列後方のpatternを削除(最短マッチ)
name%%pattern - 文字列後方のpatternを削除(最長マッチ)
name/pattern/string - 置換(一箇所)
name//pattern/string - 置換(全体)
VAR=(VAL1 VAL2 VALn)
– 配列
VAR[0]
– 配列の最初の要素
VAR[@]
– 配列の全要素
VAR[#]
– 配列の要素数
配列
(VAR1 VAR2 VAR3)
と()
(カッコ) で括って区切りを入れれば配列に変換される- コマンドの実行結果を配列化したい場合も同様
HOGE=$(ls -ld $1)
declare -a HUGA
HUGA=(${HOGE}) # 変数をカッコで括る
read -a
で入力結果を配列化
setコマンド
set -e
- スクリプト内のコマンドが失敗したらそこでスクリプトを終了する
set +e
すれば↑を解除し、失敗しても終了しなくなる
set -o 何かOPTION
set -o noclobber
– ファイルへの上書きリダイレクトを禁止するCMD >| file
と>|
を使うと強制的に上書きリダイレクト可能
条件分岐 if
,
if [ 条件 ]
if (( 算術比較式 ))
- 例えば
if [ $VAR -eq 0 ]
はif (( $VAR == 0 ))
と比較式記号で書ける - 引数の個数チェックはこう書ける
if [ $# -lt 3 ]
then
:
fi
if (( $# < 3 ))
then
:
fi
[ 条件 ]
と [[ 条件 ]]
[
はtestコマンド、[[
はbash組み込みコマンドwhich [
すると組み込みコマンドである事が分かる
- 挙動の違いは、条件式で未定義変数を使った場合
[ $UNSET_VAR = "HOGE"]
するとエラーを吐くが、[[ $UNSET_VAR = "HOGE" ]]
はエラーを吐かない
[[ 条件 ]] && { CMD1; CMDn; } || { CMDe1; CMDen; }
三項演算子
ファイルのテスト
-nt is newer than
-ot is older than
-ef have the same device and inode numbers
-b File is block special device (for files like /dev/hda1)
-c File is character special (for files like /dev/tty)
-d File is a directory
-e File exists
-f File is a regular file
-g File has its set-group-ID bit set
-h File is a symbolic link (same as -L)
-G File is owned by the effective group ID -k File has its sticky bit set
-L File is a symbolic link (same as -h) -O File is owned by the effective user ID -p File is a named pipe
-r File is readable
-s File has a size greater than zero
-S File is a socket
-u File has its set-user-ID bit set
-w File is writable
-x File is executable
-a
and, -o
or
- 複合条件はこんな感じで
\(
と\)
を使って書く –if [ -r "$FN" -a \( -f "$FN" -o -p "$FN" \) ]
文字列比較
if [ "$VAR" ]
, if [ -z "$VAR" ]
– 空判定
- 前者は “has text”, 後者は
is zero length
をチェックする
一致比較, -eq
と=
(の注意点)
-eq
は空白や前ゼロを無視して比較する
VAR1=" 05 "
VAR2="5"
# これはtrue
if [ "$VAR1" -eq "$VAR2" ]
# これはfalse
if [ "$VAR1" = "$VAR2" ]
if [[ $VAR == パターンマッチ ]]
, if [[ $VAR =~ 正規表現条件 ]]
if [[ "${MYFILENAME}" == *.jpg ]
– パターンマッチの例shopt -s OPTION
する事でパターンマッチの挙動を変更できるshopt -s extglob
– 拡張パターンマッチを使う
@( ... ) Only one occurrence *( ... ) Zero or more occurrences +( ... ) One or more occurrences ?( ... ) Zero or one occurrences !( ... ) Not these occurrences, but anything else
shopt -s nocasematch
– 大文字小文字を区別しない
if [[ "$CDTRACK" =~ "([[:alpha:][:blank:]]*)- ([[:digit:]]*) - (.*)$" ]]
– 正規表現例- マッチした部分文字列は、
BASH_REMATCH
という配列に格納される
- マッチした部分文字列は、
多岐分岐 case
,
case $FN in
*.gif) gif2png $FN # パターンマッチは大文字小文字区別しない(したければ shopt -s nocasematch)
;; # breakする
*.png) pngOK $FN
;;
*.jpg) jpg2gif $FN
;;
*.tif | *.TIFF) tif2jpg $FN # | はor条件
;;
*) printf "File not supported: %s" $FN # どの条件にもマッチしない場合
;;
esac
ループ
for 条件文
for f in /path/to/*
- パス+ワイルドカード でマッチするファイル全件のループ
for (( i=0 ; i < 10 ; i++ ))
– カウンタループ
- 元は
for i in 1 2 3 4 5 6 7 8 9 10
こう for (( i=0, j=0 ; i+j < 10 ; i++, j++ ))
複数変数を使うことも可能- 小数を使いたければ
seq
を使う(整数でも使えるが)for fp in $(seq 1.0 .01 1.1)
while 条件
- 例
while [ -z "$LOCKFILE" ]
(( ))
で算術評価式が書けるwhile (( COUNT < MAX ))
- 入力を受け付けるループ
while read READVAR
, 入力可能な間は内部では 0 を返している- EOFが来たら -1 を返す
- ファイル入力ループはこう書く
- 後者の
cat |
を使うパターンはパイプを使ってるのでサブシェルとしてループが動く=ループ内で変数を操作してもループ外に影響が出ない(影響を及ぼすことが出来ない)
- 後者の
# ファイル入力ループ
while read lineoftext
do
process that line
done < file.input
cat file.input | \
while read lineoftext
do
process that line
done
svn status mysrc | \
while read TAG FN
do
if [[ $TAG == \? ]]
then
echo $FN
rm -rf "$FN"
fi
done
- 条件 が “trueの間=戻り値が0の間”だけループが回る
1
はtrue扱い,while (( 1 ))
は無限ループ ((( 1 ))
は 0 を返している)
select
– 選択メニュー
select v in ${ARR} do ... done
ARR
の内容を元に選択メニューを表示する- 選択したindexが
${REPLY}
に、内容が${v}に設定される
DBLIST=$(sh ./listdb | tail +2)
select DB in $DBLIST
do
echo Initializing database: $DB
mysql -uuser -p $DB <myinit.sql
done
PS3
をいじると、選択プロンプトをカスタマイズ出来る
出力, リダイレクト
echo
-n
– 改行を出力しない-e
– 特殊文字を変換して出力
$ echo -e 'hi\c'
hi$
printf
$ printf '%s = %d\n' Lines $LINES
Lines = 24
$ printf '%-10.10s = %4.2f\n' 'GigaHerz' 1.92735
GigaHerz = 1.93
書式
%b
,%s
– 前者は¥n
を改行として 扱う 。後者は扱わない("¥n"
という文字列扱い)
CMD >& cmd.out
とかCMD &> cmd.out
– STDOUTとSTDERRを同じ出力先に出す
CMD > cmd.out 2>&1
この書き方よく見るけど、冗長だよね
{ CMD1; CMD2; CMDn; } > hoge.out
, (CMD1; CMD2; CMDn) > hoge.out
– 複数センテンス
{}
,()
内の全コマンドの結果をリダイレクトする{}
抜きでCMD1; CMD2; CMDn > hoge.out
と書くと、CMDn
の処理結果しかリダイレクトされない{}
はコマンドのグルーピングとして機能している()
は サブシェルが立ち上がる
{}
,()
の違い{}
はコマンドの前後に空白が必要{}
は最終コマンドの後にも;
が必要()
はサブシェルで実行される- つまり別プロセスで実行される
{ cd /tmp; ls } > hoge.out
したら実行後のpwdは/tmp
になるが、(cd /tmp; ls) > hoge.out
実行後のpwdは変わらない
ヒアドキュメント
<<EOF ... EOF
- ↓このスクリプトは期待通り動かない
# ヒアドキュメント内ではデフォルトではエスケープが効いてない
# ので "$X" のような文字列は変数として認識される
grep $1 <<EOF
# name amt
pete $100
joe $200
sam $ 25
bill $ 9
EOF
- ヒアドキュメント内をエスケープしたければ、
<<\EOF
と “EOF”の前に”\”を付ける- もしくは
'EOF'
とシングルクォートで囲む E\OF
でも動く
- もしくは
<<-EOF ...
<<-EOF
することで、ヒアドキュメント内にインデントを書くことが出来る
プロセス置換
bashのプロセス置換機能を活用して、シェル作業やスクリプト書きを効率化する – 双六工場日誌
<(コマンドリスト)
– コマンドの結果をファイルとして扱う>(コマンドリスト)
– 出力先をコマンドに渡す
ファイルディスクリプタ
[Bash]標準出力・標準エラー出力の全て(1>&2とか)まとめ | Coffee Breakにプログラミング備忘録
1
– 標準出力2
– 標準エラー出力3
以降 – 未割当
exec
と併用して色々出来る
- 出力先を変更する
# Optional, save the "old" STDERR
exec 3>&2
# Redirect any output to STDERR to an error log file instead
exec 2> /path/to/error_log
# script with "globally" redirected STDERR goes here
# Turn off redirect by reverting STDERR and closing FH3
exec 2>&3-
- Net Redirection (curlやwgetっぽい通信をbashで行う)
# Finding My IP Address
exec 3<> /dev/tcp/www.ippages.com/80 # fd 3 の入出力をtcpに割当
echo -e "GET /simple/?se=1 HTTP/1.0\n" >&3 # GETリクエストを割り当てたfdにリダイレクト
cat <&3
- プロセス置換との併用
入力
read -p "MSG " VAR
– メッセージ付き入力プロンプト
- ユーザに
MSG
を表示して入力を促し、入力内容をVAR
変数に格納する - ↓こんな関数を用意して
function choice {
CHOICE=''
local prompt="$*"
local answer
read -p "$prompt" answer
case "$answer" in
[yY1] ) CHOICE='y';;
[nN0] ) CHOICE='n';;
* ) CHOICE="$answer";;
esac
} # end of function choice
- こう呼ぶと便利かもしれない
choice "Do you want to look at the error log file? [Y/n]: "
read -s -p "MSG " PASSWD
– パスワード用入力プロンプト
-s
は文字のエコーイングをoffにするので、ユーザー入力の後に改行が表示できない- 回避策として
printf "%b" "\n"
とかすると良い
- 回避策として
- 入力したパスワード(を格納した環境変数)は、 メモリにplain textで乗っかる
/proc/core
から覗けちゃう
計算
expr 式
, $(( 式 ))
, let 式
– 計算
- ShellScript – シェルで変数のインクリメントに expr を使うと100倍遅い件 – Qiita
let
は式の中に空白を書けない=可読性が低い。$(( ))
は書ける
let Y=(X+2)*10
Y=$(( ( X + 2 ) * 10 ))
(( 算術評価式 ))
- 例えば変数の加算は…
- これはエラー →
$(( ${i}++ ))
- これもエラー →
(( ${i}++ ))
- これが正 →
(( i++ ))
(算術評価式で変数を使うのに、その内容を展開しちゃうと0++
とか1++
になっちゃう)((
の前に$
を付けない- 変数名に
$
を付けない
- これはエラー →
- 複数の変数をまとめて加減算するときの注意 =
let
を使え
$(( x+=5 , y+=8 )) # これはエラー( `$(( ))` は、別のコマンドの引数にするか、代入しないといけない)
let x+=5 y+=8 # こう書く。式の区切りはスペース
echo $(( x+=5 , y+=8 )) # カンマ演算子は第2の式の値を返すので、こう書くと y の値がechoされる
awk "BEGIN {print \"The answer is: \" $* }";
awk BEGIN
ブロックの$*
に計算式を渡すと計算結果を出力する
function calc
{
awk "BEGIN {print \"The answer is: \" $* }";
}
$ calc 2 + 3 + 4
The answer is: 9
$ calc (2+2-3)*4
-bash: syntax error near unexpected token `2+2-3'
$ calc '(2+2-3)*4'
The answer is: 4
$ calc \(2+2-3\)\*4
The answer is: 4
$ calc '(2+2-3)*4.5'
The answer is: 4.5
PATH
と hash
コマンド
bash(csh)のhashとか言う、気づかないけど便利な機能 – それマグで!
Bashのコンソールで単語移動するショートカット(https://qiita.com/odacoh/items/b94be0deecaaa27b0263)
2018/2/17追記
1文字進める/戻る、直前/直後の1文字を削除、を追加した。
(Vimに慣れてしまうと)キーボードの矢印キーの利用はできるかぎり避けたくなる。
コンソールでは、bashのデフォルトでショートカットキーが設定されているのでそれを使う。
カーソル移動系
キー | 動作 |
---|---|
Ctrl + A | カーソルを行頭へ |
Ctrl + E | カーソルを行末へ |
Ctrl + B | カーソルを1文字戻る |
Ctrl + F | カーソルを1文字進める |
ESC + F | カーソルを1単語先に進める |
ESC + B | カーソルを1単語戻す |
カーソル位置から所定の文字列を削除
キー | 動作 |
---|---|
Ctrl + K | カーソル位置から行末までを削除 |
Ctrl + U | カーソル位置から行頭までを削除 |
Ctrl + h | カーソル位置の直前の1文字を削除 |
Ctrl + d | カーソル位置の直後の1文字を削除 |
Ctrl + W | カーソル位置から単語の先頭までを削除 |
Ctrl + D | カーソル位置の文字を削除 |
なお、このショートカットキーは、bash以外でも多くのMacアプリの入力フォームで利用できる。
(なぜか、Ctrl + Aは大抵効くが、Ctrl + Eは効かないことが多い)
おまけ
ESCをモディファイアキーとして使うのは辛いので、iTerm2のエスケープシーケンスでESC→optionに変更。
これにより以下のショートカットが利用できる。
キー | 動作 |
---|---|
Opt + F | カーソルを1単語先に進める |
Opt + B | カーソルを1単語戻す |
以上
参考
Macでターミナルを使うときはショートカットキーを覚えよう!!
http://yonchu.hatenablog.com/entry/20110214/1297662332
Mac のターミナルの Bash に単語単位カーソル移動のキーバインド設定をする
http://voidptr.seesaa.net/article/395408528.html
Bash(Zsh)上でよく使うカーソル移動などのショートカットを覚えると得する話
https://qiita.com/kamykn/items/5b7f3c3eb41a3549bb4e
きっかけ
最近他人のターミナルの画面を見る機会が多くなりまして、よく矢印キーだけでカーソル移動したりする方が多いなぁと感じたりするので、紹介用にまとめました。
また、これらのショートカットを覚えることで他のLinuxコマンドなどでも通用することも多いので、ぜひ覚えておいても損はないのかなと思います。
Bash(Zsh)に存在するEmacsモードとviモード
bash、Zshなどのカーソル移動にはEmacsモードとViモードが存在します。
これらのモードはカーソル移動におけるショートカットにおいて主に違いがあります。
これらのショートカットキーはreadlineというGNUのライブラリによって提供されています。(2017-09-25 13:11 コメントの指摘より追記)
(更にコメントの指摘より追記:2017-09-27 10:33) Zshに関してはZsh Line Editorとして別途実装しているようでした。
https://wiki.archlinux.org/index.php/zsh#Key_bindings
Zsh does not use readline, instead it uses its own and more powerful Zsh Line Editor, ZLE.
(–追記ここまで–)
大抵の場合BashやZshの場合、デフォルトのEmacsモードで事足りるかと思うので、今回はBashについてはEmacsモードについてまとめます。(Viモードについて気になる方は他の方の紹介しているViモードの記事をどうぞ)
Emacsモードのカーソル移動
ショートカット | 意味 |
---|---|
Ctrl + a | カーソルを行頭に移動 |
Ctrl + e | カーソルを行末に移動 |
Alt + → ※1 | 単語ブロック毎に右に移動 ※2 |
Alt + ← ※1 | 単語ブロック毎に左に移動 ※2 |
※1 Altは適宜メタキー(Escなど)に読み替えて下さい。以降Altが記載してあれば同じように読み替えて下さい。
※2 日本語に対しても使用できますが、基本的に英語に比べると、単語ブロックの判定の精度は落ちます。
Emacsモードの文字削除
文字削除も便利なショートカットが存在します
ショートカット | 意味 |
---|---|
Ctrl + h | カーソル前の文字を削除 |
Ctrl + d | カーソル位置の文字を削除 |
Ctrl + w | 単語ブロック毎に削除 |
Ctrl + u | カーソルから行頭まで削除 |
Ctrl + k | カーソルから行末まで削除 |
ちなみに、Terminalでパスワードを入力する場面で打ち間違えたときに、Ctrl + uしたりするとパスワードを最初から打ち直したりできます。
Ctrl + w と Ctrl + h はVi(Vim)でも使えます。
Ctrl + hは地味ですが、ホームポジション崩したくない人(Vimmerとか)がよく使います[要出典]。
また、Bash、Zshにおいては行に文字が全く無い場合にはCtrl + dはexitと同じコマンドになります。
次候補、前候補
また、コマンドのヒストリーを遡る際の『候補列挙リストの移動』としての Ctrl+n Ctrl+p も同じです。
ショートカット | 意味 |
---|---|
Ctrl + n | 前のヒストリーの候補へ |
Ctrl + p | 次のヒストリーの候補へ |
この候補列挙のショートカットはVimでも補完の候補の列挙リストの移動などで利用します。
MySQLのCLIでも同様なキー操作が可能
これらのキー操作、CLIのMySQL操作でも一部同じショートカットをサポートしています。
MySQLのCLIもreadlineのライブラリによってショートカットが提供されているようです。(2017-09-25 13:11 コメントの指摘より追記)
ショートカット | 意味 |
---|---|
Ctrl + a | カーソルを行頭に移動 |
Ctrl + e | カーソルを行末に移動 |
Alt + → | 単語ブロック毎に右に移動 |
Alt + ← | 単語ブロック毎に左に移動 |
Ctrl + h | カーソル前の文字を削除 |
Ctrl + d | カーソル位置の文字を削除 |
Ctrl + u | 行を削除 |
Ctrl + w | カーソルから行頭まで削除 |
Ctrl + k | カーソルから行末まで削除 |
Ctrl + n | 前のヒストリーへ |
Ctrl + p | 次のヒストリーへ |
Ctrl + w と Ctrl + uが若干惜しい感じですが、概ねサポートしています。
また、CLIのMySQLでもCtrl + dのショートカットによるexitをサポートしています。
ほかにも、Bash、Zshと同じようにCtrl + rによるヒストリー検索もサポートしてますよね。
追記:BashとMySQLのCLIでCtrl + u Ctrl + w のショートカットの実装が異なるのは
https://dev.mysql.com/doc/refman/5.6/ja/mysql-tips.html
Unix では、キーシーケンスは mysql のビルドに使用された入力ライブラリ (たとえば、libedit または readline ライブラリ) に依存します。
とのことでした。
これらのEmacsっぽいショートカットはMacならデフォルトで利用可能
MacはこのEmacsモードのターミナルのカーソル操作に影響を受けているっぽい(それか、Emacs自体に影響を受けているか)ので、Macではおおよそ同じショートカットが利用できますので覚えておいてきっと損はありません。
ショートカット | 意味 |
---|---|
Ctrl + a | カーソルを行頭に移動 |
Ctrl + e | カーソルを行末に移動 |
Alt + → | 単語ブロック毎に右に移動 |
Alt + ← | 単語ブロック毎に左に移動 |
Ctrl + h | カーソル前の文字を削除 |
Ctrl + d | カーソル後の文字を削除 |
Ctrl + k | カーソルから行末まで削除 |
Ctrl + n | 次の候補へ (※変換中) |
Ctrl + p | 前の候補へ(※変換中) |
※Ctrl-uとCtrl-wがダメっぽいです(追記:Ctrl + u と Ctrl + w はreadlineにより提供されていないからでしょうか・・・。)
一部対応していないキーがありますが、概ね対応しているのではないかと思います。
但し、エディタによってはこれらのキーを上書きして別の機能を割り当ててしまっている場合があるのでご注意を…。
Viも色々と影響与えてますよ
ここまでEmacsのショートカットが多かったですが、Viのショートカットをサポートしているものも色々ありますよね。
カーソルの移動ではないですが、man
や --help
オプション や git diff
で開くときに使われるlessなんかもViライクなショートカットをサポートしてますよね。
ちなみに、自分はこの記事を書くまでless
コマンドで開いてたということに気づいてなかったと言うのは内緒…(viにそういう開くモードが有るもんだとばっかり思ってました…)
ショートカット | 意味 |
---|---|
j | 1行上に移動 |
k | 1行下に移動 |
d | 下にページ送り (※viだとノーマルモードでCtrl + d) |
u | 上にページ送り (※viだとノーマルモードでCtrl + u) |
g | ページ先頭へ (※viだとノーマルモードでgg) |
G | ページ終わりへ (※viだとノーマルモードでG) |
/ | ページ内検索の文字列入力開始 |
n | 次のページ内検索結果へ |
N | 次のページ内検索結果へ |
なお、less
の場合単にd,uではなくて、Ctrl + d, uでも元のショートカットと同じ挙動になります。
また、gもggも最終的には同じ場所にたどり着くので、vi使いは全く気にせず同じショートカットで使えるようになっていますよね。
qでless
コマンドを終了するのとかもviみたいですよね。
Viのショートカット体系のコマンド達
screenのコピーモードもViのようなショートカットコマンドをサポートしています。
ショートカット | 意味 |
---|---|
h | 左へ |
j | 下へ |
k | 上へ |
l | 右へ |
gg | バッファ内先頭へ |
G | バッファ内末尾へ |
Ctrl-u | 半ページ上に移動 |
Ctrl-d | 半ページ下に移動 |
/ | 検索の文字列入力開始 |
n | 次の検索結果へ |
N | 次の検索結果へ |
他にもViと同じ動作をするコマンドが幾つかあります(^,$,w,b,eなど)
他にも、個人的にはtigとかよく使ったりしますが、こちらもviライクなコマンドラインをサポートしたりしてます。
たぶん、他にもたくさんあるんだろうなーと思いつつ、思いつき次第書き込む形式で追記していきたいと思います。それかコメントで教えて下さい (←えっ…)
おまけ
webの小ネタ系でViのhjklをショートカットとしてサポートしている場合も多いですが、個人的によく使うのは、
- Google日本語入力でzh、zj、zk、zlでviの移動方向にあわせて各矢印が出る(←↓↑→)
いろいろなwebサービスでおもむろにhjklと叩くと色々と反応がある場合があって、『あぁ、意識してるんだな』感が感じられます。
まとめ
特にCLI系は新しいものに触れたときでも、Vi系やEmacs系のショートカットをサポートしているものも多いですので、特にマニュアル読まずに他で使えているショートカットを試してみるだけで意外と使えちゃったりします。
というわけで、ショートカットはEmacs系とVi系を少し覚えるだけでも決して損はないかと思いますので頑張って覚えましょう!
それでは皆さん、良いショートカットライフを!
※ この記事では便宜上Emacsライク、Viライクなショートカットというような表現をしてますが、Emacsやviが先に実装したのか、それとも他から影響を受けて、後から実装したのかについては検証しませんのでご了承下さい。