Bash を使用した最もお気に入りのコマンドライン トリックは何ですか?[閉まっている]
-
09-06-2019 - |
質問
私たちは皆使い方を知っています <ctrl>-R
履歴を逆方向に検索するには、次のような方法があることをご存知ですか? <ctrl>-S
設定した場合は前方検索します stty stop ""
?また、bind -p を実行して、キーボード ショートカットをすべてリスト表示しようとしたことはありますか?Mac OS X にはデフォルトで 455 以上あります。
bash を使用した最もお気に入りのあいまいなトリック、キーボード ショートカット、またはショッピング設定は何ですか?
解決 7
コマンドを実行するとき、前の引数を指定してコマンドを実行したい場合があります。これを行うには、次のショートカットを使用できます。
$ mkdir /tmp/new
$ cd !!:*
ファイルのリストに対して多数のコマンドを実行する必要がある場合は、find を使用する代わりに 1 行のループを開始することがあります。
for file in *.wav; do lame "$file" "$(basename "$file" .wav).mp3" ; done;
.bash_login (または .bashrc) でコマンドライン履歴オプションを構成すると、非常に便利です。以下は私が Macbook Pro で使用している設定の一部です。
次のように設定すると、履歴内の重複したコマンドを bash 消去するようになります。
export HISTCONTROL="erasedups:ignoreboth"
私も自分の歴史のサイズをかなり大きくしてみました。なぜだめですか?今日のマイクロプロセッサでは速度が低下することはないようです。
export HISTFILESIZE=500000
export HISTSIZE=100000
私が行うもう 1 つのことは、履歴からのいくつかのコマンドを無視することです。exit コマンドを覚える必要はありません。
export HISTIGNORE="&:[ ]*:exit"
必ず histappend を設定してください。そうしないと、bash は終了時に履歴を上書きします。
shopt -s histappend
私が使用するもう 1 つのオプションは cmdhist です。これにより、複数行のコマンドを 1 つのコマンドとして履歴に保存できます。
shopt -s cmdhist
最後に、Mac OS X (vi モードを使用していない場合) では、<CTRL>-S でスクロール停止をリセットします。これにより、bash が前方検索として解釈できなくなります。
stty stop ""
他のヒント
接尾辞の付いたファイルの名前変更や移動を素早く行う:
cp /home/foo/realllylongname.cpp{,-old}
これは次のように展開されます。
cp /home/foo/realllylongname.cpp /home/foo/realllylongname.cpp-old
cd -
これは、コマンドラインでの「戻る」ボタンと同等です (前のディレクトリに移動します)。
もう一つのお気に入り:
!!
最後のコマンドを繰り返します。最も役立つ形式:
sudo !!
私のお気に入りは「^string^string2」です。これは最後のコマンドを受け取り、string を string2 に置き換えて実行します。
$ ehco foo bar baz
bash: ehco: command not found
$ ^ehco^echo
foo bar baz
名前を変更する
例:
$ ls
this_has_text_to_find_1.txt
this_has_text_to_find_2.txt
this_has_text_to_find_3.txt
this_has_text_to_find_4.txt
$ rename 's/text_to_find/been_renamed/' *.txt
$ ls
this_has_been_renamed_1.txt
this_has_been_renamed_2.txt
this_has_been_renamed_3.txt
this_has_been_renamed_4.txt
とても便利です
私はのファンです !$
, !^
そして !*
Expandos は、最後に送信されたコマンド ラインから返されます。最後の項目、最初の非コマンド項目、およびすべての非コマンド項目。つまり (シェルが最初にコマンドを出力することに注意してください):
$ echo foo bar baz
foo bar baz
$ echo bang-dollar: !$ bang-hat: !^ bang-star: !*
echo bang-dollar: baz bang-hat: foo bang-star: foo bar baz
bang-dollar: baz bang-hat: foo bang-star: foo bar baz
これは、次のようなときに便利です。 ls filea fileb
, で、そのうちの 1 つを編集したいとします。 vi !$
または両方: vimdiff !*
. 。また、「 n
番目の引数」は次のようになります。
$ echo foo bar baz
$ echo !:2
echo bar
bar
最後に、パス名を追加すると、パスの一部を取得できます。 :h
そして :t
上記のいずれかのexpandoに:
$ ls /usr/bin/id
/usr/bin/id
$ echo Head: !$:h Tail: !$:t
echo Head: /usr/bin Tail: id
Head: /usr/bin Tail: id
出品方法 のみ 現在のサブディレクトリにありますか?
ls -d */
シンプルなトリックですが、それを見つけるのにどれくらいの時間がかかったのかわかりません。
ESC.
最後の bash コマンドからの最後の引数を挿入します。思った以上に便利ですよ。
cp file /to/some/long/path
CD ESC.
できますよ "diff file1.txt file2.txt
" ですが、Bash はサポートしています プロセスの置換, 、これにより、次のことが可能になります diff
コマンドの出力。
たとえば、スクリプトで期待どおりの出力が得られることを確認したいとします。スクリプトを <( ) でラップして、 diff
簡単で汚い単体テストを実行するには:
$ cat myscript.sh
#!/bin/sh
echo -e "one\nthree"
$
$ ./myscript.sh
one
three
$
$ cat expected_output.txt
one
two
three
$
$ diff <(./myscript.sh) expected_output.txt
1a2
> two
$
別の例として、2 つのサーバーに同じ RPM リストがインストールされているかどうかを確認したいとします。各サーバーに ssh するのではなく、RPM の各リストを個別のファイルに書き込み、 diff
これらのファイルに対して、私はただ次のことを行うことができます diff
私のワークステーションから:
$ diff <(ssh server1 'rpm -qa | sort') <(ssh server2 'rpm -qa | sort')
241c240
< kernel-2.6.18-92.1.6.el5
---
> kernel-2.6.18-92.el5
317d315
< libsmi-0.4.5-2.el5
727,728d724
< wireshark-0.99.7-1.el5
< wireshark-gnome-0.99.7-1.el5
$
高度なバッシュスクリプトガイドには、より多くの例があります http://tldp.org/LDP/abs/html/process-sub.html.
私のお気に入りのコマンドは「ls -thor」です
それは、 神々の力 最近変更されたファイルを読みやすい形式で一覧表示します。
むしろ斬新ですが、賢いです...
使用されている上位 10 個のコマンド:
$ history | awk '{print $2}' | awk 'BEGIN {FS="|"}{print $1}' | sort | uniq -c | sort -nr | head
出力例:
242 git
83 rake
43 cd
33 ss
24 ls
15 rsg
11 cap
10 dig
9 ping
3 vi
^R 逆検索。^R を押し、一致させる前のコマンドの一部を入力し、目的のコマンドが見つかるまで ^R を押します。そうすれば、履歴に残っている最近使用したコマンドを思い出す必要がなくなります。bash だけでなく、次のことも可能です。^E は行末、^A は行頭、^U と ^K はそれぞれカーソルの前後を削除します。
私は、vi、ls などのエイリアスをよく使用します。しかし、エイリアスを回避したい場合もあります。コマンドの前にバックスラッシュを追加するだけです。
例えば:
$ alias vi=vim
$ # To escape the alias for vi:
$ \vi # This doesn't open VIM
かっこいいですね。
ここでは、いくつかの構成の調整を示します。
~/.inputrc
:
"\C-[[A": history-search-backward
"\C-[[B": history-search-forward
これは次と同じように機能します ^R
ただし、代わりに矢印キーを使用します。これは、(例)を入力できることを意味します cd /media/
次に、上矢印を押して、最後に行った項目に移動します cd
の内側に /media/
フォルダ。
(私は Gnome ターミナルを使用しています。他のターミナル エミュレータのエスケープ コードを変更する必要がある場合があります。)
Bash の補完も非常に便利ですが、はるかに微妙な追加です。で ~/.bashrc
:
if [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
これにより、プログラムごとのタブ補完が有効になります (例:コマンドラインが次で始まるときにタブ補完を試みます evince
evince で開くことができるファイルのみを表示し、タブ補完のコマンド ライン オプションも表示します)。
これでもうまく機能します ~/.inputrc
:
set completion-ignore-case on
set show-all-if-ambiguous on
set show-all-if-unmodified on
私は次のようなものをよく使います。
の :p
履歴結果を出力する修飾子。例えば。
!!:p
最後のコマンドを出力するので、再実行する前にそれが正しいかどうかを確認できます。入力するだけです !!
それを実行するために。
同じような調子で:
!?foo?:p
履歴から文字列「foo」を含む最新のコマンドを検索し、それを出力します。
印刷する必要がない場合は、
!?foo
検索を行ってすぐに実行します。
私は秘密兵器を持っています: 貝麩。
賢いヒント、クールなトリック、効率的なレシピが何千もあり、ほとんどの場合 1 行に収まります。
私が気に入っているものは次のとおりです (ただし、Python は現在ほとんどの Unix システムにインストールされているという事実を利用しているため、少し騙しています)。
alias webshare='python -m SimpleHTTPServer'
これで、「webshare」と入力するたびに、現在のディレクトリがポート 8000 経由で利用できるようになります。USB キーやリモート ディレクトリを使わずにローカル ネットワーク上の友人とファイルを共有したい場合に非常に便利です。ビデオや音楽のストリーミングも可能です。
そしてもちろん、まったく役に立たないものの、それでもとても楽しい古典的なフォークボム:
$ :(){ :|:& };:
運用サーバーではそれを試さないでください...
watch コマンドを別のコマンドと組み合わせて使用して、変更を探すことができます。この例としては、ルーターをテストしていたときに、信号対雑音比などの最新の数値を取得したいと考えていたときがありました。
watch --interval=10 lynx -dump http://dslrouter/stats.html
type -a PROG
予想される可能性のある/usr/bin/progではなく、通常、〜/binのどこかにPROGが利用可能な場所をすべて見つけるために。
私はコマンドを構築するのが好きです エコー そしてそれらをシェルにパイプします。
$ find dir -name \*~ | xargs echo rm
...
$ find dir -name \*~ | xargs echo rm | ksh -s
なぜ?なぜなら、それを行う前に何が行われるかを確認できるからです。そうすれば、ひどいエラー (ホーム ディレクトリの削除など) が発生した場合でも、発生する前にそれをキャッチできます。明らかに、これは破壊的なアクションや取り消し不能なアクションの場合に最も重要です。
大きなファイルをダウンロードするとき、私はよく次のことを行います。
while ls -la <filename>; do sleep 5; done
完了したら、ctrl+c を押します (または、 ls
ゼロ以外を返します)。それは、 watch
プログラムですが、代わりにシェルを使用するため、シェルを使用しないプラットフォームでも動作します。 watch
.
もう 1 つの便利なツールは netcat です。 nc
. 。もし、するなら:
nc -l -p 9100 > printjob.prn
その後、別のコンピュータにプリンタを設定できますが、代わりに netcat を実行しているコンピュータの IP アドレスを使用します。印刷ジョブが送信されると、netcat を実行しているコンピュータによって受信され、ダンプされます。 printjob.prn
.
pushd
そして popd
ほとんどいつも役に立ちます
ツリー階層内の大きく離れた場所で複数のディレクトリを使用する場合に推奨されるナビゲーション方法の 1 つは、acf_func.sh (以下にリスト) を使用することです。定義したら、次のことを行うことができます
CD -
最近のディレクトリのリストを数値メニューで表示するには
cd-2
2 番目に新しいディレクトリに移動します。
とても使いやすく、とても便利です。
コードは次のとおりです。
# do ". acd_func.sh"
# acd_func 1.0.5, 10-nov-2004
# petar marinov, http:/geocities.com/h2428, this is public domain
cd_func ()
{
local x2 the_new_dir adir index
local -i cnt
if [[ $1 == "--" ]]; then
dirs -v
return 0
fi
the_new_dir=$1
[[ -z $1 ]] && the_new_dir=$HOME
if [[ ${the_new_dir:0:1} == '-' ]]; then
#
# Extract dir N from dirs
index=${the_new_dir:1}
[[ -z $index ]] && index=1
adir=$(dirs +$index)
[[ -z $adir ]] && return 1
the_new_dir=$adir
fi
#
# '~' has to be substituted by ${HOME}
[[ ${the_new_dir:0:1} == '~' ]] && the_new_dir="${HOME}${the_new_dir:1}"
#
# Now change to the new dir and add to the top of the stack
pushd "${the_new_dir}" > /dev/null
[[ $? -ne 0 ]] && return 1
the_new_dir=$(pwd)
#
# Trim down everything beyond 11th entry
popd -n +11 2>/dev/null 1>/dev/null
#
# Remove any other occurence of this dir, skipping the top of the stack
for ((cnt=1; cnt <= 10; cnt++)); do
x2=$(dirs +${cnt} 2>/dev/null)
[[ $? -ne 0 ]] && return 0
[[ ${x2:0:1} == '~' ]] && x2="${HOME}${x2:1}"
if [[ "${x2}" == "${the_new_dir}" ]]; then
popd -n +$cnt 2>/dev/null 1>/dev/null
cnt=cnt-1
fi
done
return 0
}
alias cd=cd_func
if [[ $BASH_VERSION > "2.05a" ]]; then
# ctrl+w shows the menu
bind -x "\"\C-w\":cd_func -- ;"
fi
恐ろしい Enter キーを押す前に複雑な行を展開します
- オルタナティブ+Ctrl+e — シェル展開行 (使用する必要があるかもしれません ESC, Ctrl+e キーボード上で)
- Ctrl+_ — 元に戻す
- Ctrl+バツ, * — グロブ展開ワード
$ echo !$ !-2^ *
オルタナティブ+Ctrl+e
$ echo aword someotherword *
Ctrl+_
$ echo !$ !-2^ *
Ctrl+バツ, *
$ echo !$ !-2^ LOG Makefile bar.c foo.h
&c。
私はいつも次のことに興味があります。
ctrl-E # move cursor to end of line
ctrl-A # move cursor to beginning of line
私も使っています shopt -s cdable_vars
, その後、共通ディレクトリに bash 変数を作成できます。そこで、私の会社のソース ツリー用に、次のような変数を大量に作成します。
export Dcentmain="/var/localdata/p4ws/centaur/main/apps/core"
次に、次のようにしてそのディレクトリに変更できます cd Dcentmain
.
pbcopy
これは Mac システムのクリップボードにコピーされます。コマンドをパイプすることができます...試してみてください:
pwd | pbcopy
$ touch {1,2}.txt
$ ls [12].txt
1.txt 2.txt
$ rm !:1
rm [12].txt
$ history | tail -10
...
10007 touch {1,2}.txt
...
$ !10007
touch {1,2}.txt
$ for f in *.txt; do mv $f ${f/txt/doc}; done
コマンドラインから「set -o vi」を使用するか、.bashrc で「set -o vi」を使用すると、コマンドラインで vi 編集モードになります。「挿入」モードで開始するため、通常どおりに入力したりバックスペースを入力したりできますが、「大きな」間違いを犯した場合は、esc キーを押してから、vi で行うのと同じように「b」と「f」を使用して移動できます。cwで単語を変更します。変更したい履歴コマンドを表示した後に特に便利です。
上記の多くと同様に、私の現在のお気に入りはキーストローク [alt] です。(Alt キーと「.」キーの同時押し) これは $! と同じです。(前のコマンドの最後の引数を挿入します) ただし、これは即時であり、入力するのが簡単です。(スクリプトでは使用できません)
例えば:
mkdir -p /tmp/test/blah/oops/something
cd [alt].
を使用して複数のコマンドを文字列化します。 && 指示:
./run.sh && tail -f log.txt
または
kill -9 1111 && ./start.sh