Почему Mac Terminal запоминает две последовательные команды, когда они одинаковы?

10

Я начал использовать Mac недавно и до того, как начал работать с Ubuntu.

Предположим, я запускаю эти команды одну за другой на своем терминале:

python3 main.py
python3 main2.py
python3 main2.py
python3 main2.py
python3 main2.py
python3 main2.py
python3 main2.py

Теперь предположим, что я хочу python main.pyснова запустить , поэтому я нажму клавишу вверх. Мне нужно будет нажать клавишу только дважды на Ubuntu, но 7 раз на Mac.

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

Как я могу сделать это на MacOS?

as2d3
источник
6
Просто педантично, на самом деле это не Mac Terminal. Это bash, ваша оболочка работает в терминале. Существует много оболочек, и можно и обычно заменить оболочку по умолчанию на что-то еще, например, zshи даже дальше, чтобы настроить zsh с помощью различных сценариев.
Гман

Ответы:

13

Вам нужно добавить переменную окружения HISTCONTROL в свой .bash_profile. В вашем .bash_profileдобавьте следующую строку:

export HISTCONTROL=ignoreboth:erasedups

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


Со страницы руководства дляbash (в Терминале):

HISTCONTROL
Список значений, разделенных двоеточиями, управляющий тем, как команды сохраняются в списке истории. Если в списке значений есть пробел игнорирования , строки, начинающиеся с пробела, не сохраняются в списке истории. Значение ignoredups приводит к тому, что строки, соответствующие предыдущей записи истории, не сохраняются. Значение ignoreboth является сокращением для ignorespace и ignoredups . Значение erasedups приводит к тому, что все предыдущие строки, соответствующие текущей строке, удаляются из списка истории перед сохранением этой строки. Любое значение, отсутствующее в приведенном выше списке, игнорируется. Если HISTCONTROLне задано или не содержит допустимого значения, все строки, считываемые анализатором оболочки, сохраняются в списке истории с учетом значения HISTIGNORE . Вторая и последующие строки многострочной составной команды не тестируются и добавляются в историю независимо от значения HISTCONTROL .

Аллан
источник
4

Почему это происходит?

MacOS и Ubuntu настроены по-разному для обработки дубликатов в истории команд bash. Эти конфигурации хранятся в нескольких так называемых « точечных файлах ». Они принимают форму ~ / .bash *, а также системный профиль / etc /. Все эти файлы могут быть настроены по вашему вкусу и различать интерактивные оболочки, оболочки входа в систему, удаленные оболочки и т. Д. Эти файлы читаются в определенном порядке и выполняют определенные функции.

Как получить такое же поведение на macOS?

Если вы хотите именно эту единственную настройку «игнорирования точных дубликатов командных строк», вы можете пойти с чем-то вроде ответа Аллана, то есть добавить одну единственную строку, например, в ваш файл bash_profile. Нет «правильного пути», но есть бесчисленное множество вариантов.

Если это не единственная настройка для вашего bash, то это может быть не лучшим вариантом:

Несколько других заметок:

  • Все, что должно быть доступно для графических приложений ИЛИ для sh (или bash, вызываемого как sh), ДОЛЖНО быть в ~ / .profile
  • ~ / .bashrc не должен ничего выводить
  • Все, что должно быть доступно только для оболочек входа, должно идти в ~ / .profile
  • Убедитесь, что ~ / .bash_login не существует.

Это означает , что, когда ситуация становится более сложной это хорошая идея , чтобы разложить в настройках на несколько файлов, каждый из которых специализируется и высокоупорядоченную в их содержание:

Все exportsмогут находиться в своем собственном файле для упрощенного надзора.

Создайте файл, который будет прочитан bash в корневом каталоге вашего пользовательского каталога, например, .exportsкоторый содержит:

# Omit duplicates and commands that begin with a space from history.
export HISTCONTROL='ignoreboth'; 

Это должно быть "получено", чтобы bash читал файл при интерактивном запуске:

Sourcing files
Если у вас много конфигураций оболочки, вы можете разделить их на несколько субфайлов и использовать встроенную программу-источник для загрузки их из вашего .bashrc: с добавлением source ~/.exportsв него.

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

if [ -f ~/.exports ]; then
. ~/.exports
fi

Команда . ~/.exportsбудет исходить ~/.exportsиз контекста текущей запущенной оболочки.

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

LаngLаngС
источник
2
Как .exportsполучить чтение (источник)?
fd0
1
@ fd0, само по себе это не происходит в macOS. Ответ Аллана - правильный способ достичь этого.
user3439894
Если значение HISTCONTROLустановлено в .bashrcи ~/.bashrcпоступают в ~/.bash_profileтом нет никакой необходимости exportв HISTCONTROLпеременном. И интерактивная оболочка входа в систему, и интерактивная оболочка будут иметь установленную переменную.
fd0
@ fd0 Точно: если . / В случае, если я не понимаю: моя цель состояла в том, чтобы предоставить альтернативу одновременно опубликованному Аллану A / и сохранять esp _profile, а также остальное как можно более чистым и аккуратным, потому что это для сценария, где рассматривается множество опций / настроек. Является ли ваш последний пункт предложением добавить или иметь в виду исправление, поскольку вы можете воспринимать вышеупомянутый метод как «неправильный»? Теперь, я прочитал ваш комментарий, как между моим и Алланом в уровне сложности адресов?
LаngLаngС
1

Для уникальной записи каждой новой команды сложно. Сначала вам нужно добавить ~/.profileили аналогичный:

HISTCONTROL=erasedups
PROMPT_COMMAND='history -w'

Затем вам нужно добавить в ~/.bash_logout:

history -a
history -w
Стивен Пенни
источник