Скрытые функции Bash

Сценарии оболочки часто используются как клей, для автоматизации и простых одноразовых задач. Каковы некоторые из ваших любимых "скрытых" функций языка Bash shell/scripting?

  • Одна функция для каждого ответа
  • Приведите пример и краткое описание функции, а не ссылку на документацию
  • Обозначьте эту функцию, используя полужирный заголовок в качестве первой строки

См. также:

Ответ 1

вставить предыдущий конечный параметр строки

alt - . самая полезная комбинация клавиш, попробуйте и посмотрите, почему-то никто не знает об этом.

нажмите его снова и снова, чтобы выбрать более старые параметры.

отлично, если вы хотите сделать что-то еще, что вы использовали всего лишь минуту назад.

Ответ 2

Если вы хотите продолжить выполнение процесса после выхода из системы:

disown -h <pid>

- полезный bash встроенный. В отличие от nohup, вы можете запустить disown в уже запущенном процессе.

Сначала остановите свою работу с помощью control-Z, получите pid из ps (или используйте echo $!), используйте bg, чтобы отправить его на задний план, затем используйте disown с флагом -h.

Не забудьте заполнить свою работу или она будет убита при выходе из системы.

Ответ 3

Почти все, что указано в разделе "РАСШИРЕНИЕ" в руководстве

В частности, расширение параметра:

$ 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

Ответ 4

Мой любимый:

sudo !!

Повторите предыдущую команду с помощью sudo.

Ответ 5

Дополнительные комбинации клавиш:

  • 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

Ответ 6

Получить команды истории и аргументы истории

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

Вы можете проверить свои последние команды с помощью 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
    

Ответ 7

Мне нравится функция -x, позволяющая увидеть, что происходит в вашем script.

bash -x script.sh 

Ответ 8

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

СЕКУНД

Каждый раз, когда этот параметр ссылка, количество секунд так как вызов оболочки возвращается. Если для SECONDS присвоено значение, значение, возвращенное после ссылок - количество секунд поскольку присвоение плюс значение назначены. Если SECONDS не установлен, это теряет свои особые свойства, даже если это впоследствии reset.

Ответ 9

Специальная переменная random:

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

Ответ 10

Вот один из моих любимых. Это устанавливает завершение табуляции, чтобы не было чувствительности к регистру. Это действительно отлично подходит для быстрого ввода путей к каталогам, особенно на Mac, где по умолчанию файловая система не чувствительна к регистру. Я помещал это в .inputrc в мою домашнюю папку.

set completion-ignore-case on

Ответ 11

Обработка регулярных выражений

Недавние bash релизы поддерживают регулярное выражение, поэтому вы можете:

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

где REGEX является необработанным регулярным выражением в формате, описанном человеком re_format.

Совпадения между любыми скобками хранятся в массиве BASH_REMATCH, начиная с элемента 1 (элемент 0 - это согласованная строка целиком), поэтому вы можете использовать это для синтаксического анализа с использованием regex.

Ответ 12

Быстрая и грязная коррекция опечаток (особенно полезно для длинных команд по медленным соединениям, где использование истории команд и прокрутка через нее было бы ужасно):

$ 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

Чтобы заменить old на new (один раз) во второй и последней команде.

Ответ 13

Ctrl x Ctrl e

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

Использование vi в качестве редактора:

export VISUAL=vi

Ответ 14

Здесь два моих любимых:

Чтобы проверить синтаксис без действительного выполнения script, используйте:

bash -n script.sh

Вернитесь к последнему каталогу (да, я знаю pushd и popd, но это быстрее)

cd -

Ответ 15

Использование булевых операторов Infix

Рассмотрим простое, если:

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

Это похоже на уродство. Не очень современный. Если вы используете двойные скобки вокруг своего логического выражения, вы можете использовать обычные логические операторы!

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

Ответ 16

Массивы:

#!/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.

Ответ 17

Выполнение команды перед отображением приглашения bash

Задайте команду в переменной env "PROMPT_COMMAND" и она будет запущена автоматически перед каждым приглашением. Пример:

[[email protected]]$ export PROMPT_COMMAND="date"
Fri Jun  5 15:19:18 BST 2009
[[email protected]]$ ls
file_a  file_b  file_c
Fri Jun  5 15:19:19 BST 2009
[[email protected]]$ ls

Для следующих april fools добавьте "export PROMPT_COMMAND = cd" кому-то .bashrc, затем откиньтесь назад и наблюдайте, как запутанность разворачивается.

Ответ 18

Магические комбинации клавиш на страницах bash man:

  • Ctrl + a и Ctrl + e переместите курсор в начало и конец текущей строки соответственно.

  • Ctrl + t и Alt + t транспонируйте символ и слово перед курсором с текущим, а затем переместите курсор вперед.

  • Alt + u и Alt + l преобразуйте текущее слово (от курсора до конца) в верхний и нижний регистры.

    Подсказка: Нажмите Alt + , а затем одну из этих команд, чтобы преобразовать начало текущего слова.


Бонус man подсказки:

  • При просмотре страниц man используйте / для поиска текста на страницах. Используйте n, чтобы перейти к следующему совпадению или n для предыдущего совпадения.

  • Скопируйте поиск определенной команды или подраздела на страницах man, воспользовавшись их форматированием:

    o Вместо того, чтобы вводить /history expansion, чтобы найти этот раздел, попробуйте /^history, используя карету (^), чтобы найти только строки, начинающиеся с "history".

    o Попробуйте /   read с несколькими ведущими пробелами для поиска этой встроенной команды. Встроенные элементы всегда отступают на страницах man.

Ответ 19

export TMOUT=$((15*60))

Завершить bash после 15 минут простоя, установить на 0 для отключения. Обычно я помещаю это в ~/.bashrc в мои корневые учетные записи. Это удобно при администрировании ваших ящиков, и вы можете забыть выйти из системы, прежде чем покинуть терминал.

Ответ 20

Отменить

C-S-- Ctrl Shift Minus Отменяет действия ввода.

Убить/Янки

Любая операция удаления C-w (удалить предыдущее слово), C-k (удалить до конца строки), C-u (удалить до начала строки) и т.д.... копирует его удаленный текст в кольцо убийства, вы может вставить последнее убитие с помощью: C-y и циклически (и вставлять) кольцо удаленных элементов с помощью Alt-y

Ответ 21

Вы можете игнорировать определенные файлы во время выполнения вкладки, установив переменную th FIGNORE.

Например, если у вас есть репозиторий subverion и вы хотите более легко перемещаться,

export FIGNORE=".svn"

теперь вы можете cd не блокироваться каталогами .svn.

Ответ 22

Использование арифметики:

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

Ответ 23

Расширение брекета

Стандартное разложение с {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

Ответ 24

Недавно я прочитал Программирование Csh, считающееся вредоносным, в котором содержался этот потрясающий камень:

Рассмотрим трубопровод:

A | B | C

Вы хотите знать статус C, ну, это легко: он в $?, или $статус в csh. Но если вы хотите этого от A, вам не повезло - если вы находитесь в csh, то есть. В оболочке Bourne вы можете получить ее, хотя делать это немного сложно. Здесь кое-что, что я должен был сделать, где я запустил dd's stderr в трубу grep -v, чтобы избавиться от шума ввода/вывода, но для возврата статуса выхода dd, а не grep's:

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;

Ответ 25

Обрезать содержимое файла (файл обнуления)

> file

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

Ответ 26

Не какая-то особенность, а скорее направление: я нашел много "скрытых функций", секретов и различной полезности bash в commandlinefu.com. Многие из самых высоко оцененных ответов на эти ответы я узнал их на этом сайте:)

Ответ 27

Еще один маленький: Alt + #

комментирует текущую строку и перемещает ее в буфер истории.

Итак, когда вы собираете командную строку, и вам нужно выдать промежуточную команду, например. найдите файл, вы просто нажмете alt + #, выполните другую команду, зайдите в историю, раскомментируйте и продолжите.

Ответ 28

Скобки вместо do и done для цикла

Тело цикла

For обычно находится в do...done (просто пример):

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

Но мы можем использовать стиль C с помощью фигурных скобок:

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

Я думаю, что это выглядит лучше, чем do...done, и я предпочитаю этот. Я еще не нашел это в любой документации Bash, так что это действительно скрытая функция.

Ответ 29

Числовые выражения стиля 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 ""

Ответ 30

Эти свойства являются еще одним из моих любимых.

export HISTCONTROL=erasedups
export HISTSIZE=1000

Первый гарантирует, что bash не выполняет команды журнала более одного раза, действительно улучшит полезность history. Другой расширяет размер истории до 1000 из 100 по умолчанию. Я фактически установил это на 10000 на мои машины.