Bash: «номер истории» против «номера команды»


11

Пока я гуглю, как настроить приглашение оболочки через переменную PS1, я вижу таблицы специальных символов, которые можно использовать. В частности:

          \!     the history number of this command
          \#     the command number of this command

«Номер истории», кажется, более часто используется, и я знаю, как использовать такие команды, как !523для восстановления команд из истории. Но я не могу понять, имеет ли «номер команды» аналогичные функции. Я попытался вставить \#свою переменную PS1, и она, похоже, выводит количество команд, введенных в конкретном сеансе (в отличие от того \!, который сохраняется после выхода из системы / выхода).

Кто-нибудь знает, как использовать «номер команды» удобным или осмысленным способом?


2
Я довольно глубоко искал в сети - насколько я могу судить, этот «номер команды» ценен лишь постольку, поскольку он говорит вам, сколько команд вы ввели. Я не могу найти способ использовать этот номер в интерактивном режиме, как при расширении истории
Lagrangian

1
Интересный вопрос. Если вы сделаете этот комментарий ответом, я бы проголосовал за него.
Питер Кордес

Ответы:


1

Номер команды Bash только для отображения.

Сначала немного предыстории из bashref:

Номер команды и номер истории обычно различаются: номер истории команды - это ее позиция в списке истории, которая может включать команды, восстановленные из файла истории (* примечание Bash History Facilities: :), а номер команды - это положение в последовательности команд, выполняемых во время текущего сеанса оболочки.

Погружаясь через источник, parse.yмы видим, что '\#'разрешается глобальная статическая переменная current_command_number:

case '#':                                                                     
  n = current_command_number;                                                 
  /* If we have already incremented current_command_number (PS4,              
 ${var@P}), compensate */                                                     
  if (orig_string != ps0_prompt && orig_string != ps1_prompt && orig_string != ps2_prompt)
n--;                                                                          
  temp = itos (n);                                                            
  goto add_string;                                                            

который имеет только одно использование: in eval.c, он увеличивается при запуске команды:

# ...
current_command_number++;                                                  

executing = 1;                                                             
stdin_redir = 0;                                                           

execute_command (current_command);                                         

Все, что хранится, это число, а не фактическая команда или даже эквивалентный номер истории. Таким образом, при выполнении каждой команды bash забывает, какая команда связана с каким номером команды, делая номер команды непригодным для чего-либо, кроме ссылки на просмотр и прокрутку.


5

Насколько я могу судить (и это, кажется, подтверждается вашими исследованиями), нет способа ссылаться на это магическое число в интерактивном режиме, а не через fcили !nярлыки. Похоже, что они, безусловно, относятся только к абсолютной позиции в списке истории, а не к относительной позиции с момента запуска этой конкретной оболочки (что \#означает, как вы правильно указали).

Единственный способ сделать это лучше - установить следующее:

export HISTFILESIZE=1001
export HISTSIZE=-1

Сюда:

  1. начинается история нового сеанса 1000, что облегчает определение того, где я нахожусь в сеансе
  2. (несколько не связано) я не теряю старую историю в данном сеансе (но все равно не заливаю файл)

По сути, это изменило мой измененный запрос ( PS1="\\!$ ") из:

499$ 

чтобы:

1000$ 

... что делает его немного чище при запуске. Но это, вероятно, не тот ответ, который вы искали. :)

(Кстати, я также посмотрел на zsh для решения, и кажется, что оно просто не имеет эквивалента \#, так что это тоже не помогает.)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.