Скрытые функции 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 на мои машины.