Какая у вас самая любимая трюк в командной строке с помощью Bash?

Мы все знаем, как использовать <ctrl>-R для обратного поиска по истории, но знаете ли вы, что вы можете использовать <ctrl>-S для пересылки поиска, если вы установили stty stop ""? Кроме того, вы когда-нибудь пробовали запустить bind -p, чтобы просмотреть все ваши быстрые клавиши? По умолчанию для Mac OS X установлено более 455.

Каков ваш самый любимый неясный трюк, комбинация клавиш или настройка магазина с помощью bash?

Ответ 1

При запуске команд иногда мне нужно запустить команду с предыдущими аргументами. Для этого вы можете использовать этот ярлык:

$ mkdir /tmp/new
$ cd !!:*

Иногда, вместо использования find, я вырываю однострочный цикл, если мне нужно запустить кучу команд в списке файлов.

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

Еще одна вещь, которую я делаю, - игнорировать некоторые команды из моей истории. Не нужно помнить команду выхода.

export HISTIGNORE="&:[ ]*:exit"

Вы определенно хотите установить histappend. В противном случае bash перезаписывает вашу историю при выходе.

shopt -s histappend

Другим вариантом, который я использую, является cmdhist. Это позволяет сохранять многострочные команды в историю как одну команду.

shopt -s cmdhist

Наконец, в Mac OS X (если вы не используете режим vi), вы захотите reset <CTRL> -S от остановки прокрутки. Это предотвращает возможность bash интерпретировать его как прямой поиск.

stty stop ""

Ответ 2

Переименование/перемещение файлов с помощью суффиксов быстро:
cp /home/foo/realllylongname.cpp{,-old}

Это расширяется до:
cp /home/foo/realllylongname.cpp /home/foo/realllylongname.cpp-old

Ответ 3

cd -

Это эквивалент командной строки кнопки "Назад" (переносит вас в предыдущий каталог, в котором вы были).

Ответ 4

Другой фаворит:

!!

Повторяет вашу последнюю команду. Наиболее полезно в форме:

sudo !!

Ответ 6

переименования

Пример:

$ 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

Так полезно

Ответ 7

Я поклонник !$, !^ и !* 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 и хотите отредактировать один из них: vi !$ или оба из них: vimdiff !*. Он также может быть обобщен на "n th аргумент" следующим образом:

$ echo foo bar baz
$ echo !:2
echo bar
bar

Наконец, с именами путей вы можете попасть в части пути, добавив :h и :t к любому из вышеперечисленных расширений:

$ ls /usr/bin/id
/usr/bin/id
$ echo Head: !$:h  Tail: !$:t
echo Head: /usr/bin Tail: id
Head: /usr/bin Tail: id

Ответ 8

Как перечислить только подкаталоги в текущем?

ls -d */

Это простой трюк, но вы не знаете, сколько времени мне нужно было найти!

Ответ 9

ESC .

Вставляет последние аргументы из вашей последней команды bash. Это пригодится больше, чем вы думаете.

cp file /to/some/long/path

cd ESC .

Ответ 10

Конечно, вы можете "diff file1.txt file2.txt", но Bash поддерживает замещение процесса, что позволяет diff выводить команд.

Например, скажем, я хочу убедиться, что мой script дает мне результат, который я ожидаю. Я могу просто обернуть свой script в <() и передать его на diff, чтобы получить быстрый и грязный unit test:

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

В качестве другого примера, скажем, я хочу проверить, установлен ли на обоих серверах один и тот же список RPM. Вместо того, чтобы записывать каждый сервер, записывая каждый список 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
$

В Расширенный Bash -Scripting Guide в http://tldp.org/LDP/abs/html/process-sub.html.

Ответ 11

Моя любимая команда: ls -thor

Он вызывает силу богов, чтобы отображать самые последние измененные файлы в удобном для чтения формате.

Ответ 12

Больше новизны, но она умна...

Используемые 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

Ответ 13

^ R обратный поиск. Hit ^ R, введите фрагмент предыдущей команды, которую вы хотите сопоставить, и нажмите ^ R, пока не найдете тот, который вы хотите. Тогда мне не нужно помнить недавно использованные команды, которые все еще находятся в моей истории. Не только bash, но также: ^ E для конца строки, ^ A для начала строки, ^ U и ^ K для удаления до и после курсора соответственно.

Ответ 14

У меня часто есть псевдонимы для vi, ls и т.д., но иногда вы хотите избежать псевдонима. Просто добавьте обратную косую черту в команду впереди:

Например:

$ alias vi=vim
$ # To escape the alias for vi:
$ \vi # This doesn't open VIM

Прохладный, не так ли?

Ответ 15

Здесь несколько настроек настройки:

~/.inputrc:

"\C-[[A": history-search-backward
"\C-[[B": history-search-forward

Это работает так же, как ^R, но вместо этого использует клавиши со стрелками. Это означает, что я могу напечатать (например) cd /media/, затем нажать стрелку вверх, чтобы перейти к последней вещью я cd 'd в папку /media/.

(Я использую терминал Gnome, вам может понадобиться изменить escape-коды для других эмуляторов терминалов.)

Bash завершение также невероятно полезно, но это гораздо более тонкое дополнение. В ~/.bashrc:

if [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
fi

Это позволит выполнить пополнение каждой программы (например, попытка завершения вкладки, когда командная строка начинается с evince, будет отображать только файлы, которые могут открываться, и также будет включать в себя параметры командной строки).

Хорошо работает с этим также в ~/.inputrc:

set completion-ignore-case on
set show-all-if-ambiguous on
set show-all-if-unmodified on

Ответ 16

Я использую следующее много:

Модификатор :p, чтобы распечатать результат истории. Например.

!!:p

Выведет последнюю команду, чтобы вы могли проверить ее правильность перед ее повторным запуском. Просто введите !!, чтобы выполнить его.

В аналогичном ключе:

!?foo?:p

Будет искать вашу историю для самой последней команды, содержащей строку 'foo' и печатать ее.

Если вам не нужно печатать,

!?foo

выполняет поиск и выполняет его сразу.

Ответ 17

У меня есть секретное оружие: shell-fu.

Есть тысячи умных советов, классных трюков и эффективных рецептов, которые большую часть времени подходят для одной линии.

Тот, который мне нравится (но я немного обманываю, так как я использую тот факт, что Python установлен в большинстве Unix-систем):

alias webshare='python -m SimpleHTTPServer'

Теперь каждый раз, когда вы печатаете "webshare", текущий каталог будет доступен через порт 8000. Действительно приятно, когда вы хотите обмениваться файлами с друзьями в локальной сети без ключа usb или удаленного каталога. Потоковое видео и музыка тоже будут работать.

И, конечно же, классическая боковая вилка, которая абсолютно бесполезна, но все равно очень веселая:

$ :(){ :|:& };:

Не пытайтесь сделать это на рабочем сервере...

Ответ 18

Вы можете использовать команду watch вместе с другой командой для поиска изменений. Например, когда я тестировал свой маршрутизатор, и я хотел получать обновленные номера на таких вещах, как отношение сигнал/шум и т.д.

watch --interval=10 lynx -dump http://dslrouter/stats.html

Ответ 19

Мне нравится создавать команды с echo и передавать их в оболочку:

$ find dir -name \*~ | xargs echo rm
...
$ find dir -name \*~ | xargs echo rm | ksh -s

Почему? Потому что это позволяет мне посмотреть, что будет сделано, прежде чем я это сделаю. Таким образом, если у меня есть ужасная ошибка (например, удаление моего домашнего каталога), я могу поймать ее до того, как это произойдет. Очевидно, что это наиболее важно для деструктивных или безотзывных действий.

Ответ 20

type -a PROG

чтобы найти все места, где имеется PROG, обычно где-то в ~/bin а не тот, который можно было ожидать в/usr/bin/PROG.

Ответ 21

При загрузке большого файла я довольно часто делаю:

while ls -la <filename>; do sleep 5; done

А затем просто ctrl + c, когда я закончил (или если ls возвращает ненулевое значение). Он похож на программу watch, но вместо этого использует оболочку, поэтому он работает на платформах без watch.

Другим полезным инструментом является netcat или nc. Если вы выполните:

nc -l -p 9100 > printjob.prn

Затем вы можете настроить принтер на другом компьютере, но вместо этого использовать IP-адрес компьютера, на котором выполняется netcat. Когда задание на печать отправляется, он принимается компьютером, на котором запущен netcat, и сбрасывается в printjob.prn.

Ответ 22

pushd и popd почти всегда пригодится

Ответ 23

Один из предпочтительных способов навигации, когда я использую несколько каталогов в разных местах иерархии дерева, - это использовать acf_func.sh(см. ниже). После определения вы можете сделать

cd -

чтобы просмотреть список последних каталогов с числовым меню

cd -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

Ответ 24

Разверните сложные строки, прежде чем попасть в опасный вход

  • Alt + Ctrl + e — shell-expand-line (может потребоваться использовать Esc, Ctrl + e на вашей клавиатуре)
  • Ctrl + _ — отменить
  • Ctrl + x, * — Glob расширяющееся слово

$echo !$ !-2^ * Alt + Ctrl + e
$ echo aword someotherword * Ctrl + _
$ echo !$ !-2^ * Ctrl + x, *
$ echo !$ !-2^ LOG Makefile bar.c foo.h

&. С

Ответ 25

Я всегда был частичным:

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.

Ответ 26

pbcopy

Это копируется в буфер обмена Mac. Вы можете передавать команды на него... try:

pwd | pbcopy

Ответ 27

$ 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

Ответ 28

Используя 'set -o vi' из командной строки или, лучше, в .bashrc, помещает вас в режим редактирования vi в командной строке. Вы начинаете в режиме "вставки", чтобы вы могли вводить и возвращать как обычно, но если вы совершаете "большую" ошибку, вы можете нажать клавишу esc, а затем использовать "b" и "f" для перемещения, как вы это делаете в vi. cw, чтобы изменить слово. Особенно полезно после создания команды истории, которую вы хотите изменить.

Ответ 29

Сгруппируйте несколько команд вместе с помощью команды &&:

./run.sh && tail -f log.txt

или

kill -9 1111 && ./start.sh

Ответ 30

Подобно многим выше, моим текущим фаворитом является нажатие клавиши [alt]. (Клавиши Alt и "." Вместе) это то же самое, что и $! (Вставляет последний аргумент из предыдущей команды), за исключением того, что он немедленный и для меня более легкий для ввода. (Просто не может использоваться в скриптах)

например:

mkdir -p /tmp/test/blah/oops/something
cd [alt].