Bash HISTSIZE против HISTFILESIZE?

В чем разница между HISTSIZE и HISTFILESIZE?

Они используются для расширения истории bash за пределами 500 строк по умолчанию.

Кажется, что здесь нет ясности и на других форумах, почему они оба нужны. (Пример 1, Пример 2, Пример 3).

Ответ 1

Короткий ответ:

HISTSIZE - это количество строк или команд, которые хранятся в памяти в списке истории, пока ваша сессия bash продолжается.

HISTFILESIZE - это количество строк или команд, которые (a) разрешены в файле истории во время запуска сеанса, и (b) сохранены в файле истории в конце сеанса bash для использования в будущих сеансах.

Обратите внимание на различие между file: на диске - и list: в памяти.

Длинный ответ:

Вся информация выше + несколько примеров:

Пример 1: HISTFILESIZE=10 и HISTSIZE=10

  1. Вы начинаете свою сессию.
  2. Ваш HISTFILE (файл, в котором хранится история команд bash), усекается до HISTFILESIZE = 10 строк.
  3. Вы пишете 50 строк.
  4. В конце ваших 50 команд, в вашем списке истории только команды с 41 по 50, размер которых определяется как HISTSIZE = 10.
  5. Вы заканчиваете свою сессию.
  6. Предполагая, что histappend не включен, команды с 41 по 50 сохраняются в вашем HISTFILE, который теперь содержит 10 команд, которые он удерживал в начале, плюс 10 вновь написанных команд.
  7. Ваш HISTFILE урезан до HISTFILESIZE = 10 строк.
  8. Теперь у вас есть 10 команд в вашей истории - последние 10, которые вы только что набрали в сеансе, который вы только что завершили.
  9. Когда вы начинаете новый сеанс, вы начинаете с 1 с HISTFILE HISTFILESIZE = 10.

Пример 2: HISTFILESIZE=10 и HISTSIZE=5

  1. Вы начинаете свою сессию.
  2. Ваш HISTFILE (файл, в котором хранится история команд bash), усекается до не более HISTFILESIZE = 10 строк.
  3. Вы пишете 50 строк.
  4. В конце ваших 50 команд, в вашем списке истории только команды с 46 по 50, размер которых определяется как HISTSIZE = 5.
  5. Вы заканчиваете свою сессию.
  6. Предполагая, что histappend не включен, команды с 46 по 50 сохраняются в вашем HISTFILE, который теперь содержит 10 команд, которые он держал в начале, плюс 5 вновь написанных команд.
  7. Ваш HISTFILE урезан до HISTFILESIZE = 10 строк.
  8. Теперь у вас есть 10 команд в вашей истории - 5 из предыдущего сеанса и последние 5, которые вы только что набрали в сеансе, который вы только что завершили.
  9. Когда вы начинаете новый сеанс, вы начинаете с 1 с HISTFILE HISTFILESIZE = 10.

Пример 3: HISTFILESIZE=5 и HISTSIZE=10

  1. Вы начинаете свою сессию.
  2. Ваш HISTFILE (файл, в котором хранится история команд bash), усекается до не более HISTFILESIZE = 5 строк.
  3. Вы пишете 50 строк.
  4. В конце ваших 50 команд, в вашем списке истории только команды с 41 по 50, размер которых определяется как HISTSIZE = 10.
  5. Вы заканчиваете свою сессию.
  6. Предполагая, что histappend не включен, команды с 41 по 50 сохраняются в вашем HISTFILE, который теперь содержит 5 команд, которые он удерживал в начале, плюс 10 вновь написанных команд.
  7. Ваш HISTFILE урезан до HISTFILESIZE = 5 строк.
  8. Теперь у вас есть 5 команд в вашей истории - последние 5, которые вы только что набрали в сеансе, который вы только что закончили.
  9. Когда вы начинаете новый сеанс, вы начинаете заново с шага 1 с HISTFILE из HISTFILESIZE = 5.

Информация от elixir_sinari:

История файла не обновляется при вводе команд. Команды хранятся в "списке" отдельно (доступ к команде истории). Количество этих сохраненных команд контролируется значением HISTSIZE. Когда оболочка (интерактивная) завершается, последние строки $ HISTSIZE копируются/добавляются в $ HISTFILE из этого "списка". Если HISTFILESIZE установлен, то после этой операции гарантируется, что в $ HISTFILE существуют только строки $ HISTFILESIZE (самые последние). И когда оболочка запускается, "список" инициализируется от $ HISTFILE до максимум команд $ HISTSIZE.

И со страницы man bash:

Значение переменной HISTSIZE используется в качестве количества команд для сохранения в списке истории. Текст последних команд HISTSIZE (по умолчанию 500) сохраняется. (...)

При запуске история инициализируется из файла, названного переменной HISTFILE (по умолчанию ~/.bash_history). Файл, названный значением HISTFILE, усекается, если необходимо, чтобы он содержал не более количества строк, указанных значением HISTFILESIZE. (...) При выходе из интерактивной оболочки последние строки $ HISTSIZE копируются из списка истории в $ HISTFILE. Если включена опция оболочки histappend (см. Описание shopt в разделе "Команды SHELL BUILTIN" ниже), строки добавляются в файл истории, в противном случае файл истории перезаписывается. Если HISTFILE не установлен или файл истории недоступен для записи, история не сохраняется. (...) После сохранения истории файл истории усекается, чтобы в нем содержалось не более строк HISTFILESIZE. Если HISTFILESIZE не установлен, усечение не выполняется.

Ответ 2

Основываясь на том, что сказал arturomp, и в попытке сделать его немного яснее.

У вас есть 2000-долгая история.

~$ history
    1  sdf
    2  fghdfgjf
    3  fghfghdf
   ..  ..
 2027  78
 2028  57
 2029  yu45u

Вы можете сократить то, что вы показываете с помощью HISTSIZE

~$ HISTSIZE=5
~$ history
 2026  546
 2027  78
 2028  56
 2029  yu45u
 2030  HISTSIZE=5

Теперь, независимо от того, сколько команд вы набираете, будут записаны только последние 5.

~$ ABC
~$ GGH
~$ GSDHFG
~$ JFDR
~$ ABSDDS
~$ AHFGHFD
<close terminal>
<open new terminal>
~$ history
    1  sdf
    2  fghdfgjf
    3  fghfghdf
   ..  ..
 2028  56
 2029  yu45u
 2030  HISTSIZE=5
 2031  GGH
 2032  GSDHFG
 2033  JFDR
 2034  ABSDDS
 2035  AHFGHFD

Мы можем ясно видеть, что наша первая команда ( "ABC" ) не находится в истории, поскольку записаны только последние 5 команд.

Теперь общая история хранится в файле (.bash_history), и вы можете изменить, как долго этот файл будет получен с помощью HISTFILESIZE. Например, с 2033 HISTFILESIZE, в моем случае я бы получил следующее:

~$ history
    1  fghfghdf
    2  gegege
    3  gege
   ..  ..
 2028  HISTSIZE=5
 2029  GGH
 2030  GSDHFG
 2031  JFDR
 2032  ABSDDS
 2033  AHFGHFD