1) PROMPT_COMMAND
Возможно, вы уже в курсе, как манипулировать приглашением prompt, чтобы показать различную полезную информацию, но не все знают, что каждый раз при показе приглашения можно запускать команду оболочки.
На самом деле многие сложные манипуляторы prompt используют эту переменную, чтобы выполнять команды для сбора информации, которая отображается в приглашении.
Попробуйте запустить это в новом шелле, и увидите, что произойдёт с сессией:
$ PROMPT_COMMAND='echo -n "writing the prompt at " && date'
2) HISTTIMEFORMAT
Если запустить
history
в консоли, вы получите список команд, ранее выполненных под вашей учётной записью.$ HISTTIMEFORMAT='I ran this at: %d/%m/%y %T '
Как только установлена эта переменная, новые записи записывают время вместе с командой, поэтому выдача будет выглядеть так:
1871 I ran this at: 01/05/19 13:38:07 cat /etc/resolv.conf
1872 I ran this at: 01/05/19 13:38:19 curl bbc.co.uk
1873 I ran this at: 01/05/19 13:38:41 sudo vi /etc/resolv.conf
1874 I ran this at: 01/05/19 13:39:18 curl -vvv bbc.co.uk
1876 I ran this at: 01/05/19 13:39:25 sudo su -
Форматирование соответствует символам из man date.
3) CDPATH
Чтобы сэкономить время в командной строке, можете использовать эту переменную для изменения каталогов так же легко, как вы вызываете команды.
Как и
PATH
, переменная CDPATH
представляет собой список путей, разделённых двоеточием. Когда вы запускаете команду cd
с относительным путём (т. е. без слэша в начале), по умолчанию оболочка ищет в вашей локальной папке соответствующие имена. CDPATH
будет искать в путях, которые вы дали для каталога, куда хотите перейти.Если установить
CDPATH
таким образом:$ CDPATH=/:/lib
а затем ввести:
$ cd /home
$ cd tmp
то вы всегда попадёте в
/tmp
независимо от того, где находитесь.Однако осторожно, потому что если не указать в списке локальную (
.
) папку, то вы не сможете создать любую другую папку tmp
и перейти к ней, как обычно:$ cd /home
$ mkdir tmp
$ cd tmp
$ pwd
/tmp
Упс!
Это похоже на путаницу, которую я почувствовал, когда понял, что локальная папка не была включена в более знакомую переменную
PATH
… но вы должны сделать это в переменной PATH, потому что вас могут обмануть, запустив фейковую команду из какого-нибудь скачанного кода.Моя устанавливается начальной точкой:
CDPATH=.:/space:/etc:/var/lib:/usr/share:/opt
4) SHLVL
Вы когда-нибудь задумывались, ввод
exit
выведет вас из текущей оболочки bash в другую «родительскую» оболочку или просто полностью закроет окно консоли?Эта переменная отслеживает, насколько глубоко вы вложены в оболочку bash. Если создать новый терминал, то он установлен на 1:
$ echo $SHLVL
1
Затем, если запустить другой процесс оболочки, число увеличивается:
$ bash
$ echo $SHLVL
2
Это может быть очень полезно в скриптах, где вы не уверены, следует выходить или нет, или отслеживать, где вы находитесь по вложенности.
5) LINENO
Также для анализа текущего состояния и отладки полезна переменная
LINENO
, которая сообщает количество команд, выполненных в сеансе к настоящему моменту:$ bash
$ echo $LINENO
1
$ echo $LINENO
2
Это чаще всего используется при отладке скриптов. Вставляя такие строки, как
echo DEBUG:$LINENO
, вы можете быстро определить, где в скрипте вы находитесь (или нет).6) REPLY
Если, как я, вы обычно пишете такой код:
$ read input
echo do something with $input
то может стать сюрпризом, что не нужно вообще беспокоиться о создании переменной:
$ read
echo do something with $REPLY
Это делает то же самое.
7) TMOUT
Чтобы не оставаться на продакшн-серверах слишком долго в целях безопасности или случайно не запустить что-нибудь опасное в неправильном терминале, установка этой переменной действует как защита.
Если ничего не вводится в течение установленного количества секунд, происходит выход из оболочки.
То есть это альтернатива
sleep 1 && exit
:$ TMOUT=1
Комментарии (32)
mayorovp
13.05.2019 09:17Это похоже на путаницу, которую я почувствовал, когда понял, что локальная папка не была включена в более знакомую переменную PATH… но вы должны сделать это в переменной PATH, потому что вас могут обмануть, запустив фейковую команду из какого-нибудь скачанного кода.
Хотел я спросить на каком это вообще языке написано и зачем при переводе был искажен смысл, но когда я залез в оригинальную статью — там оказалась написана такая же чепуха.
На всякий случай поясняю о чем тут на самом деле речь: нельзя добавлять. в PATH, поскольку из-за этого могут переопределиться базовые команды шелла, как случайно, так и намеренно из-за действий злоумышленника. Так, вызывая
ls
, хочется быть уверенным что это именно/bin/ls
, а вовсе не./ls
anton19286
13.05.2019 09:20-1семь переменных, десять ядов, эксперты назвали пять продуктов вызывающих пригорание.
просить убавить кликбейтное давление смысла нет?
как ощущать себя товаром и продолжать получать удовольствие?atomlib
13.05.2019 10:14Радикально менять название невозможно, поскольку это перевод.
Что не так с заголовком этого текста?
Предположим, это была бы написанная с нуля статья. Какое бы вы предложили название для неё?anton19286
13.05.2019 10:41-1Интереса ради погуглил clickbait bingo.
Из четырех слов заголовка два оттуда.Voiddancer
13.05.2019 11:06Так вы предложите альтернативу то.
lagranzh
13.05.2019 12:04о мало известных возможнoстях bash?
Voiddancer
13.05.2019 12:09Но вы не упомянули что речь про, так сказать, системные переменные bash.
lagranzh
13.05.2019 12:46-1А и не надо. Про это есть в статье. То что эти возможности контролируются переменными, уже подробности имплементации. я так думаю :)
Evengard
13.05.2019 13:41+1Вот это точно кликбейт, когда из заголовка не ясен смысл, и приходится открывать статью чтоб разобраться, при том что тема интересная. А так всё ясно и понятно. Нормальный заголовок.
immaculate
13.05.2019 15:50Я давно перешел на fish. Переучивание было немного утомительным. Некоторые вещи работают не так как в bash/zsh, и знания, за 20+ лет пробороздившие мозг, периодически приводят к попыткам написать как в bash.
Но одна вещь, которая вымораживает и из-за которой нет ни малейшего желания возвращаться. bash теряет историю. Да, у них в ChangeLog как минимум однажды писали, что эта проблема исправлена. Нет, не исправлена. Какие бы настройки истории я не использовал, рано или поздно возникает ситуация, когда я набираю
Ctrl-R ansible-
, и не вижу ровным счетом ничего. А потом гляжу в историю, и вижу, что она в очередной раз обнулилась. Обычно это случается в самый неподходящий момент, когда ты пытаешься срочно что-то починить или задеплоить.
За много лет регулярные полные и частичные потери истории так меня достали, что я поклялся никогда не использовать bash в интерактивном режиме. Скрипты продолжаю писать на нем, так как он есть в каждой системе по умолчанию, даже в Windows уже.
red_andr
13.05.2019 19:39+1Не всегда так просто можно поменять shell, зачастую есть корпоративный стандарт, а какой-нибудь fish вообще не установлен. История да, это проблема в bash. Я решил её для себя сохраняя в файл, можно даже после каждой команды используя упомянутый тут PROMPT_COMMAND. А потом ещё и делая бакап этих файлов. Так что, не обязательно утомительно переучиваться. Плохо это или хорошо, но bash есть везде. Ну почти везде, не считая совсем урезанных версий на контроллерах.
vvzvlad
13.05.2019 23:59+1Я решил её для себя сохраняя в файл, можно даже после каждой команды используя упомянутый тут PROMPT_COMMAND.
А как?nad_oby
14.05.2019 00:26У меня пока прижился вот такой вариант, немного сложный, но для меня работает.
Тут синхронизируется история между всеми сессиями на хосте (это упрощённая версия, на самом деле синхронизируется история для всех сессий с одной домашней директорией, например хомяк на NFS)
Последняя строка срабатывает при каждом логине это «очистка» истории от «мусора» и не обязательна.
export HISTCONTROL=ignoreboth:erasedups export PROMPT_COMMAND="history -n; history -w; history -c; history -r" TMPFILE=$(mktemp); tac "${HISTFILE}" | sed -e 's/[[:space:]]*$//' | awk '!x[$0]++' | tac > "${TMPFILE}" ; cat "${TMPFILE}" > "${HISTFILE}" ; rm "${TMPFILE}"; unset TMPFILE
vvzvlad
14.05.2019 17:43У меня в PROMPT_COMMAND было, оказывается, добавлено «history -a», но все равно не работало — между разными сессиями не синхронизировалось. Попробовал заменить на ваш вариант.
Aldrog
13.05.2019 20:26Для меня оказалось проще перейти на zsh. В нём после настройки с история ведёт себя хорошо, есть фичи, которых в баше не хватает, а синтаксис после bash гораздо привычнее, чем у fish.
netch80
13.05.2019 23:16-1Хранение истории в bash (точнее, в общем readline) действительно ужасно.
Это как раз то место, куда напрашивается применить sqlite :)
Alatarum
14.05.2019 09:22> он есть в каждой системе по умолчанию, даже в Windows уже.
А вот это спорное утверждение. В бсд, например, по умолчанию нету, пока не вытянется с чем-нибудь по зависимостям. Более того, /bin/sh там ВНЕЗАПНО действительно указывает на sh.
Но это ещё ладно, его, неожиданно, по дефолту нету в Убунте, а под его именем скрывается dash, который хоть и совместим с башем в большей части, но бывают сюрпризы (иначе откуда бы я узнал, что там на самом деле не баш?).
Ну и да, в эмбеддед обычно бизибокс, который тоже не совсем баш.
Вообще, ситуация с этими подменами маразмотична, ИМХО, а тема башизмов давно избита. Поэтому я лично никогда не буду использовать эти 'неожиданные' переменные, дабы не выстрелить себе в ногу. И вообще, писать предпочитаю на sh.
PS: в интерактивной режиме баша ещё раздражает например, что по умолчанию стрелки вверх/вниз тупо листают историю, а pgup/pgdown работают не везде, и что ^W стирает весь путь целиком. Поэтому всю жизнь пользовался tcsh, zsh или fish.
iig
13.05.2019 15:51Почему неожиданных то? Редко используемых — возможно. Что неожиданного в том, что есть в man bash (даже то, что его до конца не читают — это ожидаемо ;))? Если переменная PROMPT_COMMAND указывает, какую команду использовать при отображении приглашения — это ожидаемо. Вот если бы эта переменная включала, к примеру, debug mode — это было бы действительно неожиданно.
ogost
13.05.2019 19:03+310 лет на Линукс и с bash, а они продолжают меня удивлять. Спасибо за перевод, многое узнал впервые. Уж гораздо интереснее, чем типичные "n лайфхаков в командной строке", где в 100500-тый раз опишут что-то вроде Ctrl+R или "cd -"
nick_gabpe
13.05.2019 20:01+1Не считаю себя крутым линуксоидом, но о трёх возможностях знал. Тут просто как повезёт: нужно будет — узнаешь, если не нужно будет, то и не будешь об этом знать. Хотя кому-то явно будет полезно.
maxzhurkin
13.05.2019 21:47+1CDPATH может испортить не только настроение, но и сборку средствами make, например
Voiddancer
Я плохой линуксоид если не знал ни про одну из этих возможностей?
mickvav
Нет. Вы просто не читали
man bash
. Оно вообще занятное — массивы там всякие, сокеты, хитрые подстановки переменных.Sirikid
Возможно вы просто не используете баш, это, несомненно, правильный выбор.
Voiddancer
Использую, но там где надо что-то сложнее пары сравнений предпочитаю питон.
khim
Как человек знающий-таки bash (и даже эти переменные)… могу вас только поддержать.
bash — это ужасная вещь. Он начала создаваться ещё в 70е, когда о безопасности никто не думал, а когда начали думать — то добавили костылей. Что при этом не удалось сделать — так это сделать так, чтобы простые методы были бы безопасны.
В результате любую задачу в bash можно сделать 10 разными способами из коготорых 9 простых — на самом деле не всегда работают.
Использовать язык, в котором такого количества мин нету где возможно — очень разумное решение…
Zverik
Хороший линуксоид — не тот, кто всё знает, а тот, кто каждый день учится :)