web-dev-qa-db-ja.com

Bashの隠された機能

シェルスクリプトは、自動化や単純な1回限りのタスクの接着剤としてよく使用されます。 Bashシェル/スクリプト言語のお気に入りの「隠された」機能は何ですか?

  • 回答ごとに1つの機能
  • ドキュメントへのリンクだけでなく、機能の例と簡単な説明を提供する
  • 最初の行として太字のタイトルを使用してフィーチャにラベルを付けます

こちらもご覧ください:

72
Patrick

前の行の最終パラメータを挿入

alt-. これまでで最も便利なキーの組み合わせを試してみてください。何らかの理由で誰もこのキーのことを知りません。

何度も何度も押して、古い最後のパラメーターを選択します。

ちょっと前に使ったものに何か他のことをしたいときに最適です。

69
chillitom

ログアウト後にプロセスを実行したい場合:

disown -h <pid>

組み込みの便利なbashです。 Nohupとは異なり、すでに実行中のプロセスでdisownを実行できます。

まず、control-Zを使用してジョブを停止し、psからpidを取得し(またはecho $!を使用)、bgを使用してバックグラウンドに送信し、次にdisownを使用します-hフラグ。

ジョブをバックグラウンドで実行することを忘れないでください。ログアウトすると、ジョブが強制終了されます。

40
Alex Reynolds

マニュアルの拡張セクションにリストされているほぼすべて

特に、パラメーター展開:

$ 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
38
Vinko Vrsalovic

お気に入り:

Sudo !!

前のコマンドをSudoで再実行します。

35
GloryFish

その他の魔法のキーの組み合わせ:

  • Ctrl + r コマンド履歴から「逆インクリメンタル検索」を開始します。入力を続けると、入力したすべてのテキストを含む最新のコマンドが取得されます。

  • Tab あいまいでない場合は、これまでに入力したWordを補完します。

  • TabTab これまでに入力したWordのすべての補完をリストします。

  • 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 CtrlAlt + e
    ls -N --color=tty -T 0 /home/cramey

27
Adam Liss

履歴コマンドと引数を取り戻す

!演算子を使用して、以前のコマンドと引数に選択的にアクセスできます。長いパスで作業しているときに非常に便利です。

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
    
24
Jaime Soriano

スクリプトで何が起こっているかを確認できる-x機能が気に入っています。

bash -x script.sh 
20
stephanea

SECONDS=0; sleep 5 ; echo "that took approximately $SECONDS seconds"

[〜#〜] seconds [〜#〜]

このパラメーターが参照されるたびに、シェル呼び出しが返されてからの秒数。値がSECONDSに割り当てられている場合、以降の参照で返される値は、割り当てから割り当てられた値を加えた秒数です。 SECONDSが設定されていない場合、その後リセットされても特別なプロパティは失われます。

19

これが私のお気に入りの一つです。これにより、タブ補完で大文字と小文字が区別されなくなります。特にデフォルトでファイルシステムが大文字と小文字を区別しないMacでは、ディレクトリパスをすばやく入力するのに非常に便利です。これをホームフォルダーの.inputrcに配置します。

set completion-ignore-case on
17
danieljimenez

特別な変数random:

if [[ $(($RANDOM % 6)) = 0 ]]
    then echo "BANG"
else
    echo "Try again"
fi   
16
Vinko Vrsalovic

CtrlxCtrle

これにより、変数VISUALで定義されたエディターに現在のコマンドがロードされます。これは、ここにリストされているコマンドのような長いコマンドに非常に役立ちます。

エディターとしてviを使用するには:

export VISUAL=vi
13
Robin

正規表現の処理

最近のbashリリースには正規表現の一致機能があるため、次のことができます。

if [[ "mystring" =~ REGEX ]] ; then  
    echo match
fi

rEGEXは、man re_formatで記述された形式の生の正規表現です。

括弧で囲まれた部分からの一致は、要素1から始まるBASH_REMATCH配列に格納されます(要素0は完全に一致した文字列です)。これを使用して、正規表現を使用した解析も実行できます。

13
th_in_gs

誤字をすばやく修正する(コマンド履歴を使用してスクロールするのが恐ろしい低速接続での長いコマンドに特に便利です):

$ cat /proc/cupinfo
cat: /proc/cupinfo: No such file or directory
$ ^cup^cpu

!:s/old/newも試してください。これは、前のコマンドで古いものを新しいものに1回置き換えます。

多数のオカレンスを置換する場合は、!:gs/old/newを使用してグローバル置換を実行できます。

gsおよびsコマンドは、任意の履歴イベントで使用できます。

!-2:s/old/new

最後から2番目のコマンドでoldnew(1回)に置き換えるには。

13
mihi

ここで私のお気に入りの2つ:

実際にスクリプトを実行せずに構文を確認するには、次を使用します。

bash -n script.sh

最後のディレクトリに戻ります(はい、私はpushdとpopdを知っていますが、これは速いです)

cd -
10
André

配列:

#!/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スクリプト記述)の詳細については、 Advanced Bash-Scripting Guide を参照してください。

8
JesperE

Bash manページからのマジックキーの組み合わせ:

  • Ctrl + a そして Ctrl + e カーソルをそれぞれ現在の行の先頭と末尾に移動します。

  • Ctrl + t そして Alt + t 現在のカーソルとカーソルの前の文字と単語を入れ替えてから、カーソルを前に移動します。

  • Alt + u そして Alt + l 現在のWordを(カーソルから最後まで)大文字と小文字に変換します。

    ヒント:押す Alt +  次に、これらのコマンドのいずれかを続けて、現在のWordのbeginningを変換します。


ボーナスmanヒント:

  • manページを表示しながら、 / ページ内のテキストを検索します。使用する n 次の試合にジャンプするか、 N 前回の試合。

  • 書式設定を利用して、manページ内の特定のコマンドまたはサブセクションの検索を高速化します。

    o入力する代わりに /history expansion そのセクションを見つけるには、試してください /^history、キャレット(^) "history。"で始まるbeginの行のみを検索します。

    o試してみる /   read、いくつかの先行スペースを使用して、その組み込みコマンドを検索します。ビルトインは、常にmanページでインデントされます。

8
Adam Liss

中置ブール演算子の使用

単純な場合を考えてみましょう:

if [ 2 -lt 3 ]
    then echo "Numbers are still good!"
fi

それはちょっとltいように見えます。あまり現代的ではありません。ブール式を二重括弧で囲むと、通常のブール演算子を使用できます!

if [[ 2 < 3 ]]
    then echo "Numbers are still good!"
fi
8
Patrick

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」を追加してから、座って混乱が広がるのを見てください。

8
Shawn Chin

Th FIGNORE変数を設定することにより、タブ補完中に特定のファイルを無視できます。

たとえば、サブバージョンのレポがあり、より簡単にナビゲートしたい場合

export FIGNORE=".svn"

cdにブロックされることなく.svnディレクトリ。

7
Sionide21

export TMOUT=$((15*60))

アイドル時間の15分後にbashを終了し、0に設定して無効にします。通常、これをルートアカウントの〜/ .bashrcに配置します。ボックスを管理するときに便利です。端末から離れる前にログアウトするのを忘れることがあります。

7
Mike Nelson

Undo

C-S--コントロールシフトマイナス 入力操作を元に戻します。

キル/ヤンク

削除操作 C-w (以前のWordを削除)、 C-k (行末まで削除)、 C-u (行の先頭まで削除)など...削除されたテキストを削除リングにコピーします。最後の削除を貼り付けるには: C-y 削除されたアイテムのリングを循環して(そしてそこから貼り付けて) Alt-y

7
ocodo

ブレースの拡張

{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
5
Tom

算術の使用:

if [[ $((2+1)) = $((1+2)) ]]
    then echo "still ok"
fi
5
Vinko Vrsalovic

別の小さなもの: Alt+#

現在の行をコメントアウトして、履歴バッファに移動します。

そのため、コマンドラインを組み立てているときに、仮コマンドを発行する必要がある場合ファイルを見つけたら、Alt +#を押して、他のコマンドを発行し、履歴を上に移動し、コメントを外して続行します。

4
neurolabs

実際には機能ではなく、方向性: commandlinefu.com で、多くの「隠された機能」、秘密、およびさまざまなbashの有用性を見つけました。この回答に対する最も評価の高い回答の多くは、そのサイトでそれらを学びました:)

4
Agos

forループ内のdoおよびdoneの代わりに中括弧

Forループ本体は通常do...done(単なる例):

for f in *;
do
    ls "$f";
done

しかし、中括弧を使用してCスタイルを使用できます。

for f in *; {
    ls "$f";
}

これはdo...doneそして私はこれを好む。 Bashのドキュメントでこれをまだ見つけていないので、これは本当に隠された機能です。

4
Fish Monitor

最近読んだ Cshプログラミングは有害と見なされた この驚くべき宝石が含まれていた:

パイプラインを検討してください。

A | B | C

Cのステータスを知りたいのであれば、それは簡単です。それは$?にあるか、cshにある$ statusです。しかし、もしあなたがAからそれを望むなら、あなたは運が悪い-あなたがcshにいるなら、それはそうです。 Bourne Shellでは入手できますが、そうするのは少し難しいです。ここでは、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;
4
Greg Hewgill

ファイルの内容を切り捨てる(ファイルをゼロにする)

> file

具体的には、これは、ファイルが別のプロセスによって開かれている場合にログファイルを切り捨てるのに非常に適しています。

4
Thevs

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 ""
3
Steve Baker

これらのプロパティは、私のお気に入りの1つです。

export HISTCONTROL=erasedups
export HISTSIZE=1000

1つ目は、bashがコマンドを2回以上ログに記録しないようにし、historyの有用性を本当に向上させます。もう1つは、履歴サイズをデフォルトの100から1000に拡張します。実際にマシンでこれを10000に設定します。

3
danieljimenez

複数のディレクトリ間を簡単に移動する

隠された機能ではありませんが、スタックのようなナビゲーションを必要とするpushdよりもはるかに柔軟です。

a() { alias $1=cd\ $PWD; }

cdのどこかにa 1と入力します。後で1と入力するだけで、そのディレクトリに戻ります。

3
David Plumpton

set -o viコマンド履歴と現在入力されているコマンドをviのように編集するため。

3

私がよく使うのは、最後のコマンドの最後の単語を参照するための!$です。

$ less foobar.txt
...
# I dont want that file any more
$ rm !$
3
camh

エイリアス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>

もちろん、そのようなことにはメイクファイルがありますが、エイリアスが有用であることを示したと思います。

私はこのエイリアスの使用をあまり必要としませんでしたが、このエイリアスを持っていることが嬉しかったことがあります!

2
Alok Singhal

他の人が述べたように、 Ctrl-r コマンド履歴をさかのぼるのに最適です。しかし、1つまたはいくつかのステップを多すぎた後に前進したい場合はどうでしょうか。それはどこですか Ctrl-s 便利になります。ただし、通常はXOFF(割り込みデータフロー)にマップされます。低速のシリアル端末を使用していないため、これはあまり有用ではないため、次の方法でマッピングをオフにできます。

stty -ixon

あなたの~/.bashrcファイル。

これはまた Ctrl-q 通常は複製である利用可能 Ctrl-v (リテラル制御文字を挿入できる引用符付き挿入)。私が持っています Ctrl-q menu-completeにマップされ、繰り返し押すと補完が実行されます。私は去るのが好き Tab 通常の完了に設定します。

設定できます Ctrl-q この行を~/.inputrcファイル:

"\C-q": menu-complete
2

ここでは文字列<<<)。 Bashマニュアルには次の説明があります。

Wordは展開され、標準入力でコマンドに提供されます。

例:

$ cat<<<"$(( 10*3+1 )) Nice isn't it?"
31 Nice isn't it?
2
artistoex

Bashには、間接的な変数があります。

$ foo=bar
$ baz=foo
$ echo ${!baz}
bar
2

特別なソケットファイル名:/ 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 と併用すると非常に便利です。

http://thesmithfam.org/blog/2006/05/23/bash-socket-programming-with-devtcp-2/ からのより高度な例= wgetにアクセスできない場合、またはカール:

$ 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
1
Tom

<(cmd ...)または>(cmd ...)によるプロセス置換

各フォームでは、入力または出力がFIFOに接続された状態でcmdが実行され、その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
1
Tom

基本的な算術に '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"
1
Shawn Chin

http://linuxconfig.net/manual-howto/key-combinations-in-bash.html でBashのキーの組み合わせに関する詳細情報を取得します。

0
GEvorg

埋め込みコマンドの置換:

ホスト名&& Dig + short $(ホスト名)&& Dig + short -x $(Dig + short $(ホスト名))

このコマンドは、メールサーバーのRDNSを確認するのに適しています。 :P

0
Nathacof

クイック履歴検索

以下は、便利で簡単な履歴検索のような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、UpArrowと入力します。 grep -ri myText .のようなものが表示されます

0