Bash: „numer historii” vs „numer polecenia”

11

Podczas, gdy Google dostosowuje mój monit powłoki za pomocą zmiennej PS1, widzę tabele znaków specjalnych, których można użyć. W szczególności:

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

Wydaje się, że „numer historii” jest częściej używany i wiem, jak używać poleceń, takich jak !523ponawianie poleceń z historii. Ale nie mogę ustalić, czy „numer polecenia” ma podobną funkcjonalność. Próbowałem wprowadzić \#zmienną PS1 i wydaje się, że wypisuje ona liczbę poleceń wprowadzonych w danej sesji (w przeciwieństwie do tej \!, która utrzymuje się po wylogowaniu / wyjściu).

Czy ktoś wie, jak używać „numeru polecenia” w wygodny lub znaczący sposób?

Lagrangian
źródło
2
Szukałem dość głęboko w sieci - o ile wiem, ten „numer polecenia” jest cenny tylko w takim stopniu, w jakim informuje o liczbie wprowadzonych poleceń. Nie mogę znaleźć sposobu na użycie tego numeru interaktywnie, jak w przypadku ekspansji historii
Lagrangian
1
Interesujące pytanie. Jeśli uczynisz ten komentarz odpowiedzią, zagłosuję na niego.
Peter Cordes,

Odpowiedzi:

1

Numer polecenia Basha służy wyłącznie do wyświetlania.

Najpierw trochę tła z bashref:

Numer polecenia i numer historii są zwykle różne: numer historii polecenia jest jego pozycją na liście historii, która może obejmować polecenia przywrócone z pliku historii (* uwaga Bash History Facilities: :), podczas gdy numerem polecenia jest pozycja w sekwencji poleceń wykonywanych podczas bieżącej sesji powłoki.

Nurkując przez źródło, parse.ywidzimy, że '\#'rozwiązuje to globalna zmienna statyczna 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;                                                            

który ma tylko jedno zastosowanie: w eval.cjest zwiększany po uruchomieniu polecenia:

# ...
current_command_number++;                                                  

executing = 1;                                                             
stdin_redir = 0;                                                           

execute_command (current_command);                                         

Przechowywana jest tylko liczba, a nie rzeczywiste polecenie lub nawet równoważny numer historii. Tak więc, po wykonaniu każdego polecenia, bash zapomina, które polecenie jest powiązane z danym numerem polecenia, czyniąc numer polecenia niezdatnym do użytku dla celów innych niż wyświetlanie i przewijanie.

biskup
źródło
5

O ile mogę powiedzieć (i to wydaje się być potwierdzone przez badania), nie ma możliwości, aby odnieść się do tej magicznej liczby interaktywnie, lub nie przez fclub !nskrótów. Wydaje się, że z pewnością odnoszą się one tylko do absolutnej pozycji na liście historii, a nie do pozycji względnej od momentu uruchomienia tej konkretnej powłoki (do której \#odnosi się waht , jak słusznie zauważyłeś).

Jedynym sposobem, aby uczynić to przyjemniejszym tutaj, jest ustawienie następujących opcji:

export HISTFILESIZE=1001
export HISTSIZE=-1

W ten sposób:

  1. historia nowej sesji zaczyna się od 1000, co ułatwia określenie, gdzie jestem w sesji
  2. (nieco niezwiązany) Nie tracę starszej historii w danej sesji (ale nadal nie zalewam pliku)

Zasadniczo zmieniłem mój zmodyfikowany monit ( PS1="\\!$ ") z:

499$ 

do:

1000$ 

... co czyni go trochę czystszym na początku. Ale prawdopodobnie nie takiej odpowiedzi szukałeś. :)

(Nawiasem mówiąc, szukałem również rozwiązania zsh i wydaje się, że po prostu nie ma ono odpowiednika \#, więc to też nie pomaga.)

anarcat
źródło