シェル スクリプトは、自動化や単純な 1 回限りのタスクの接着剤としてよく使用されます。Bash シェル/スクリプト言語の「隠された」お気に入りの機能は何ですか?
- 回答ごとに 1 つの機能
- ドキュメントへのリンクだけでなく、機能の例と簡単な説明を提供してください
- 最初の行として太字のタイトルを使用してフィーチャにラベルを付けます
以下も参照してください。
シェル スクリプトは、自動化や単純な 1 回限りのタスクの接着剤としてよく使用されます。Bash シェル/スクリプト言語の「隠された」お気に入りの機能は何ですか?
以下も参照してください。
前の行の最終パラメータを挿入
alt-. これまでで最も便利なキーの組み合わせです。試してみてください。何らかの理由で誰もこれについて知りません。
何度も押すと、古い最後のパラメータが選択されます。
ほんの少し前に使用したものに何か別のことをしたい場合に最適です。
ログアウト後もプロセスを実行し続けたい場合:
disown -h <pid>
便利な bash 組み込みです。とは異なりnohup
、disown
すでに実行中のプロセスで実行できます。
まず、control-Z でジョブを停止し、pid を取得ps
(または を使用echo $!
) し、 を使用bg
してバックグラウンドに送信してからdisown
、-h フラグを使用します。
ジョブをバックグラウンドにすることを忘れないでください。そうしないと、ログアウト時に強制終了されます。
マニュアルの拡張セクションにリストされているほとんどすべて
特に、パラメータの拡張:
$ I=foobar
$ echo ${I/oo/aa} #replacement
faabar
$ echo ${I:1:2} #substring
oo
$ echo ${I%bar} #trailing substitution
foo
$ echo ${I#foo} #leading substitution
bar
お気に入り:
sudo !!
前のコマンドを sudo で再実行します。
Ctrl+rコマンド履歴から「逆インクリメンタル検索」を開始します。入力を続けると、入力したすべてのテキストを含む最新のコマンドが取得されます。
Tabあいまいでない場合、これまでに入力した単語を補完します。
Tab Tabこれまでに入力した単語のすべての補完を一覧表示します。
Alt+可能なすべての補完を* 挿入します。これは、ワイルドカードを使用して潜在的に破壊的なコマンドを入力したばかりの場合に特に役立ちます。
rm -r source/d*.c
Alt+*
rm -r source/delete_me.c source/do_not_delete_me.c
Ctrl+ Alt+eは、現在の行でエイリアス、履歴、およびシェル展開を実行します。つまり、現在の行がシェルによって処理されるときに再表示されます。
ls $HOME/tmp
Ctrl Alt+e
ls -N --color=tty -T 0 /home/cramey
履歴コマンドと引数を取得する
!
演算子を使用して、以前のコマンドと引数に選択的にアクセスすることができます。長いパスを扱う場合に非常に便利です。
で最後のコマンドを確認できますhistory
。
のコマンドのインデックスである!<n>
前のコマンドを使用できます。負の数は、履歴の最後のコマンドから逆方向にカウントされます。n
history
ls -l foo bar
touch foo bar
!-2
以前の引数を!:<n>
で使用できます。ゼロはコマンド、>= 1 は引数です。
ls -l foo
touch !:2
cp !:1 bar
そして、両方を組み合わせることができます!<n>:<m>
touch foo bar
ls -l !:1 !:2
rm !-2:1 !-2:2
!-2
引数の範囲も使用できます!<n>:<x>-<y>
touch boo far
ls -l !:1-2
その他の!
特別な修飾子は次のとおりです。
*
すべての引数に対して
ls -l foo bar
ls !*
^
最初の引数 ( !:1
== !^
)
$
最後の引数
ls -l foo bar
cat !$ > /dev/null
-x 機能が好きで、スクリプトで何が起こっているかを確認できます。
bash -x script.sh
SECONDS=0; sleep 5 ; echo "that took approximately $SECONDS seconds"
秒
このパラメーターが参照されるたびに、シェル呼び出しからの秒数が返されます。SECONDS に値が割り当てられている場合、後続の参照で返される値は、割り当てからの秒数に割り当てられた値を加えたものになります。SECONDS が設定されていない場合、後でリセットされても、その特別なプロパティは失われます。
これが私のお気に入りの1つです。これにより、タブ補完で大文字と小文字が区別されなくなります。ディレクトリ パスをすばやく入力するのに非常に便利です。特に、デフォルトでファイル システムの大文字と小文字が区別されない Mac では便利です。.inputrc
これをホームフォルダに入れました。
set completion-ignore-case on
特殊変数 random:
if [[ $(($RANDOM % 6)) = 0 ]]
then echo "BANG"
else
echo "Try again"
fi
Ctrlx Ctrle
これにより、現在のコマンドが変数VISUALで定義されたエディターにロードされます。これは、ここにリストされているコマンドのような長いコマンドに非常に役立ちます。
viをエディターとして使用するには:
export VISUAL=vi
タイプミスの迅速で汚い修正(特に、コマンド履歴を使用してスクロールするのがひどい低速接続での長いコマンドに役立ちます):
$ cat /proc/cupinfo
cat: /proc/cupinfo: No such file or directory
$ ^cup^cpu
また!:s/old/new
、前のコマンドで古いものを新しいものに置き換えるものを一度試してください。
多くのオカレンスを置換する場合は、でグローバル置換を行うことができます!:gs/old/new
。
gs
およびs
コマンドは、任意の履歴イベントで使用できます。
!-2:s/old/new
最後から2番目のコマンドold
で(1回)に置き換えます。new
ここに私のお気に入りの2つがあります:
スクリプトを実際に実行せずに構文を確認するには、次を使用します。
bash -n script.sh
最後のディレクトリに戻ります (はい、pushd と popd は知っていますが、こちらの方が速いです)。
cd -
配列:
#!/bin/bash
array[0]="a string"
array[1]="a string with spaces and \"quotation\" marks in it"
array[2]="a string with spaces, \"quotation marks\" and (parenthesis) in it"
echo "There are ${#array[*]} elements in the array."
for n in "${array[@]}"; do
echo "element = >>${n}<<"
done
配列(およびその他の高度なbashスクリプトに関するもの)の詳細については、高度なBashスクリプトガイドを参照してください。
中置ブール演算子の使用
次の場合は簡単に考えてください。
if [ 2 -lt 3 ]
then echo "Numbers are still good!"
fi
それはちょっと醜く見えます。あまりモダンではありません。ブール式を二重括弧で囲むと、通常のブール演算子を使用できます!
if [[ 2 < 3 ]]
then echo "Numbers are still good!"
fi
bash プロンプトを表示する前にコマンドを実行する
「PROMPT_COMMAND」環境変数にコマンドを設定すると、各プロンプトの前に自動的に実行されます。例:
[lsc@home]$ export PROMPT_COMMAND="date"
Fri Jun 5 15:19:18 BST 2009
[lsc@home]$ ls
file_a file_b file_c
Fri Jun 5 15:19:19 BST 2009
[lsc@home]$ ls
次回のエイプリルフールには、誰かの .bashrc に「export PROMPT_COMMAND=cd」を追加してから、混乱が展開するのをじっと見ていてください。
FIGNORE
変数を設定することにより、タブの完了中に特定のファイルを無視できます。
たとえば、subverionリポジトリがあり、より簡単にナビゲートしたい場合は、
export FIGNORE=".svn"
これで、ディレクトリcd
にブロックされることなく実行できます。.svn
export TMOUT=$((15*60))
15 分間のアイドル時間後に bash を終了します。無効にするには 0 に設定します。通常、これをルート アカウントの ~/.bashrc に置きます。ボックスを管理するときに便利で、端末から離れる前にログアウトするのを忘れる場合があります。
C-S-- コントロール シフト マイナス入力操作を元に戻します。
任意の削除操作C-w(前の単語C-kを削除)、(行末まで削除)、(C-u行頭まで削除) など... 削除されたテキストをキル リングにコピーし、最後のキルを次のように貼り付けることができますC-y。から貼り付けます)で削除されたアイテムのリングAlt-y
ブレースの拡張
{x,y,z} による標準展開:
$ echo foo{bar,baz,blam}
foobar foobaz fooblam
$ cp program.py{,.bak} # very useful with cp and mv
{x..y} によるシーケンス展開:
$ echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z
$ echo {a..f}{0..3}
a0 a1 a2 a3 b0 b1 b2 b3 c0 c1 c2 c3 d0 d1 d2 d3 e0 e1 e2 e3 f0 f1 f2 f3
算術演算の使用:
if [[ $((2+1)) = $((1+2)) ]]
then echo "still ok"
fi
もう一つの小さなもの: Alt+#
現在の行をコメントアウトして履歴バッファに移動します。
したがって、コマンド ラインを組み立てていて、たとえばファイルを検索するために中間コマンドを発行する必要がある場合は、alt+# を押して別のコマンドを発行し、履歴を上に移動し、コメントを解除して続行します。
実際には機能ではなく、方向性です。多くの「隠された機能」、秘密、およびさまざまな bash の有用性をcommandlinefu.comで見つけました。この回答に対する最高評価の回答の多くは、そのサイトで学びました:)
for ループの代わりdo
および中かっこdone
For
ループ本体は通常do...done
(ほんの一例) にあります。
for f in *;
do
ls "$f";
done
しかし、中括弧を使用して C スタイルを使用できます。
for f in *; {
ls "$f";
}
私はこれがより良く見えると思います、do...done
そして私はこれを好みます。これは Bash のドキュメントでまだ見つかっていないため、これは実際には隠された機能です。
私は最近、この驚くべき宝石を含むCsh Programming Considered Harmfulを読みました。
パイプラインを考えてみましょう:
A | B | C
C のステータスを知りたいのですが、それは簡単です: $? または csh の $status にあります。しかし、A から取得したい場合は不運です。つまり、csh にいる場合です。Bourne シェルでは取得できますが、取得するのは少し面倒です。これは、dd の stderr を grep -v パイプに実行してレコードのイン/アウト ノイズを取り除く必要がありましたが、grep ではなく dd の終了ステータスを返す必要があった場合です。
device=/dev/rmt8
dd_noise='^[0-9]+\+[0-9]+ records (in|out)$'
exec 3>&1
status=`((dd if=$device ibs=64k 2>&1 1>&3 3>&- 4>&-; echo $? >&4) |
egrep -v "$dd_noise" 1>&2 3>&- 4>&-) 4>&1`
exit $status;
ファイルの内容を切り捨てる (ファイルをゼロにする)
> file
具体的には、ファイルが別のプロセスによって開かれているときにログ ファイルを切り捨てるのに非常に適しています。
set -o vi
コマンド履歴と現在入力されているコマンドをviのように編集するため。
私がよく使うのは、最後のコマンドの最後の単語を参照する !$ です。
$ less foobar.txt
...
# I dont want that file any more
$ rm !$
C スタイルの数値式:
let x="RANDOM%2**8"
echo -n "$x = 0b"
for ((i=8; i>=0; i--)); do
let n="2**i"
if (( (x&n) == n )); then echo -n "1"
else echo -n "0"
fi
done
echo ""
複数のディレクトリ間を簡単に移動
隠された機能ではありませんが、スタックのようなナビゲーションを必要とする pushd よりもはるかに柔軟です。
a() { alias $1=cd\ $PWD; }
cd
どこかに入力してa 1
ください。後で入力1
するだけで、そのディレクトリに戻ります。
ここで文字列(<<<
)。Bashのマニュアルには次の説明があります。
単語は展開され、標準入力でコマンドに提供されます。
例:
$ cat<<<"$(( 10*3+1 )) nice isn't it?"
31 nice isn't it?
Bash には変数の間接化があります。
$ foo=bar
$ baz=foo
$ echo ${!baz}
bar
エイリアスがr='fc-s'
あり、限られたケースで非常に便利です。最後のコマンドを実行するには、r
入力して Enter キーを押すだけです。もちろん、それ自体はあまり役に立ちません。上向き矢印でも同じことができるからです。r
ただし、前のコマンドを置換して実行するために使用できます。最後のコマンドが、ファイルをコンパイルする長いコマンドだったとしましょう。
$ gcc -c <file_name>.c <lots of options> -o <file_name>.o
次に、同じオプションを使用して別のファイルをコンパイルし、対応する.o
ファイルを作成します。
$ r <file_name>=<new_file>
やります。上向き矢印を使用して適切な場所に移動し、それぞれを手動で置き換える必要はありません。これは複数回繰り返すことができるため、次にこれを行うことができます。
$ r <new_file>=<other_file>
もちろん、そのような場合には makefile がありますが、エイリアスが役立つことを示していただければ幸いです。
私はこのエイリアスをあまり必要としませんでしたが、このエイリアスを持っていてよかったと思ったことは何度もあります!
他の人が述べたように、Ctrl-rはコマンド履歴をさかのぼるのに最適です。しかし、1 つまたはいくつかの手順を実行しすぎた後で、先に進みたい場合はどうすればよいでしょうか。それがCtrl-s重宝します。ただし、通常は XOFF (割り込みデータ フロー) にマップされます。遅いシリアル端末を使用していないため、これはあまり役に立たないため、次のコマンドでそのマッピングをオフにできます。
stty -ixon
あなたの~/.bashrc
ファイルに。
これにより、通常は - の複製である-Ctrlも使用可能になります (リテラル制御文字を挿入できる quoted-insert )。私は- menu-complete にマップしました。これは、繰り返し押されたときに補完をステップ実行します。セットをレギュラーコンプリートのままにしておくのが好きです。qCtrlvCtrlqTab
次の行をファイルに追加することで、 Ctrl-qを menu-complete に設定できます。~/.inputrc
"\C-q": menu-complete
<(cmd ...)または>(cmd ...)によるプロセス置換
各形式で、cmdは入力または出力をFIFOに接続して実行され、そのFIFOへのパスがコマンドラインで置き換えられます。
$ echo A file to read: <(cat), a file to write to: >(cat)
A file to read: /dev/fd/63, a file to write to: /dev/fd/62
たとえば、中間ファイルを保存せずに2つのWebサイトを比較するには、次のようにします。
$ diff <(curl -s http://tldp.org/LDP/abs/html/) <(curl -s http://www.redhat.com/mirrors/LDP/LDP/abs/html/)
ファイル名を入力として受け取るコマンドがあるが、stdoutを意味する「-」を受け入れない場合は、それをだますことができます。
$ do_thingee --log -
error: can't open log file: '-'
$ do_thingee --log >(cat)
do_thingee v0.2
initializing things
processing 4 things
done
基本的な算術演算に「let」組み込み bash コマンドを使用する
A=10
let B="A * 10 + 1" # B=101
let B="B / 8" # B=12, let does not do floating point
let B="(RANDOM % 6) + 1" # B is now a random number between 1 and 6
浮動小数点評価を行うには、「bc」コマンドを使用できます (bash の一部ではありません)。
FP=`echo "scale=4; 10 / 3" | bc` # FP="3.3333"
特別なソケット ファイル名: /dev/tcp/HOST/PORT および /dev/udp/HOST/PORT
デイタイム サーバー (ポート 13) から読み取る:
$ cat < /dev/tcp/utcnist.colorado.edu/13
55786 11-08-13 03:34:21 50 0 0 172.3 UTC(NIST) *
これはtcpserverと組み合わせると非常に便利です。
wget または curl にアクセスできない場合のhttp://thesmithfam.org/blog/2006/05/23/bash-socket-programming-with-devtcp-2/からのより高度な例:
$ exec 3<>/dev/tcp/www.google.com/80 # hook up to file desc 3
$ echo -e "GET / HTTP/1.1\n\n" >&3 # send the HTTP request
$ cat <&3 # read the HTTP response
埋め込みコマンドの置換:
ホスト名 && dig +short $(ホスト名) && dig +short -x $(dig +short $(ホスト名))
このコマンドは、メール サーバーの RDNS を確認するのに適しています。:P
http://linuxconfig.net/manual-howto/key-combinations-in-bash.htmlで Bash のキーの組み合わせに関する詳細情報を入手してください。
クイック履歴検索
以下は、便利で簡単な tcsh のような履歴検索を提供します。
~/.inputrc
またはに次の行を追加します/etc/inputrc
。
$ cat ~/.inputrc
"\e[A": history-search-backward
"\e[B": history-search-forward
Esc
+など、あまり偶然ではないキーの組み合わせを使用することをお勧めしますp
。その場合は、使用します
"\ep": history-search-backward
"\en": history-search-forward
次に、最初の数文字を入力して上矢印キーを押します。指定された文字で始まる最新のコマンドが表示されます。
元:
タイプgrep
、上矢印。次のようなものが表示されますgrep -ri myText .