Bash: "número do histórico" vs "número do comando"

11

Enquanto pesquisava no Google como personalizar meu prompt de shell por meio da variável PS1, estou vendo tabelas de caracteres especiais que podem ser usados. Em particular:

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

O "número do histórico" parece ser mais comumente usado, e eu sei como usar comandos como !523refazer comandos do histórico. Mas não consigo descobrir se o "número do comando" tem uma funcionalidade semelhante. Eu tentei colocar \#minha variável PS1, e parece gerar o número de comandos digitados em uma sessão específica (ao contrário \!, que persiste após o logout / exit).

Alguém sabe como usar o "número do comando" de uma maneira conveniente ou significativa?

Lagrangiano
fonte
2
Eu pesquisei bastante profundamente na rede - o mais próximo que posso dizer, esse "número de comando" é valioso apenas na medida em que indica quantos comandos você digitou. Não consigo encontrar uma maneira de usar este número de maneira interativa, com a expansão da história
de Lagrange
1
Pergunta interessante. Se você fizer desse comentário uma resposta, eu votaria nele.
Peter Cordes

Respostas:

1

O número do comando do Bash é apenas para exibição.

Primeiro, alguns antecedentes de bashref:

O número do comando e o número do histórico geralmente são diferentes: o número do histórico de um comando é sua posição na lista do histórico, que pode incluir comandos restaurados do arquivo do histórico (* note Bash History Facilities: :), enquanto o número do comando é o posição na sequência de comandos executados durante a sessão atual do shell.

Mergulhando através da fonte, parse.yvemos que '\#'resolve a variável estática global 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;                                                            

que tem apenas outro uso: em eval.c, é incrementado ao executar um comando:

# ...
current_command_number++;                                                  

executing = 1;                                                             
stdin_redir = 0;                                                           

execute_command (current_command);                                         

Tudo o que é mantido é um número, não o comando real ou mesmo o número do histórico equivalente. Portanto, após a execução de cada comando, o bash esquece qual comando associado a qual número de comando, tornando o número do comando inutilizável para outra coisa que não seja referência de exibição e rolagem.

bispo
fonte
5

Tanto quanto eu posso dizer (e isso parece confirmado por sua pesquisa), não há como se referir a esse número mágico interativamente, ou não através de fcou !natalhos. Esses certamente parecem se referir apenas à posição absoluta na lista do histórico, não à posição relativa desde que esse shell específico foi iniciado (o que é o que se \#refere, como você apontou corretamente).

A única maneira que encontrei para tornar isso mais agradável aqui é definir o seguinte:

export HISTFILESIZE=1001
export HISTSIZE=-1

Dessa maneira:

  1. o histórico de uma nova sessão começa em 1000, o que facilita a identificação de onde estou em uma sessão
  2. (um pouco independente) não perco o histórico antigo em uma determinada sessão (mas ainda não inundo o arquivo)

Basicamente, ele virou meu prompt modificado ( PS1="\\!$ ") de:

499$ 

para:

1000$ 

... o que o torna um pouco mais limpo no início. Mas essa provavelmente não é a resposta que você estava procurando. :)

(A propósito, eu também procurei no zsh por uma solução, e parece que ele simplesmente não tem o equivalente \#, então isso também não ajuda em nada.)

anarcat
fonte