
Если на терминале bash я выполню следующий цикл for:
for i in {1..5}; do echo $i; done
Команды echo
не добавляются в историю текущей оболочки. Это потому, что команды в for (в do
разделе) запускаются в подоболочке? Если так, есть ли способ запустить их в текущей оболочке? Или это невозможно, потому что она «запускается» for
в данный момент?
Редактировать: Учитывая, что весь цикл for рассматривается как одна составная команда, если я удалю цикл for и запишу отдельные команды в пять строк, разве все пять не должны быть добавлены в историю?
Я сделал следующее:
#!/bin/bash
set -o history
var=5
echo $((var--))
echo $((var--))
echo $((var--))
echo $((var--))
echo $((var--))
и запустил скрипт с помощью source
. В истории все еще отображается только один оператор echo echo $((var--))
, а не все пять. С другой стороны, если вместо пяти echo $((var--))
я ввожу пять команд echo 5
, echo 4
, ... echo 1
, все пять добавляются в историю.
Почему?
решение1
Ваш скрипт вообще не будет сохранять историю в ~/.bash_history, если вы не экспортируете $HISTFILE
его перед запуском. Как говорится в man bash
этом, потому что:
Если HISTFILE не установлен или файл истории недоступен для записи, история не сохраняется.
HISTFILE
это не переменная окружения, это переменная оболочки и поэтому она недоступна в скриптах, которые являются дочерними процессами. И даже если вы запустили эти команды
$ var=5
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
(обратите внимание на пробелы после приглашения) в интерактивном сеансе, а не в скрипте, они не будут сохранены в ~/.bash_history на практике, поскольку популярные дистрибутивы Linux, такие как Ubuntu, настроены
HISTCONTROL
на ignorespace
или ignoreboth
(что является псевдонимом для
ignorespace
и ignoredups
), чтобы не сохранять команды, которые начинаются с одного или нескольких пробелов. Это особенно полезно, если вы работаете на общем сервере с другими пользователями и намеренно не хотите сохранять заданную команду в истории, чтобы другие люди могли ее увидеть, например, потому что она содержит ваш пароль или другую конфиденциальную информацию.
Но даже если бы перед командой не было пробелов:
$ var=5
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
$ echo $((var--))
вы, скорее всего, получите только одну echo $((var--))
запись в ~/.bash_history, поскольку HISTCONTROL
обычно содержит
ignoredups
или вышеупомянутый ignoreboth
. Все это описано в HISTCONTROL
разделе на странице руководства Bash, которую вы можете вызвать man bash
в своей системе.