I Linux lagras en logg över alla kommandon du utför, och denna historik är sökbar, vilket möjliggör återanvändning av tidigare kommandon. Att förstå hur Linux historikfunktionen fungerar kan avsevärt öka din effektivitet.
Hantera kommandohistoriken
Som George Santayana klokt konstaterade, ”De som inte minns sitt förflutna är dömda att upprepa det.” I Linux-världen, om du inte har tillgång till ditt förflutna (i form av kommandon), blir det svårt att upprepa tidigare handlingar, även om du vill.
Här kommer Linux kommandohistorik in i bilden. Den låter dig granska och återanvända tidigare kommandon. Syftet är inte enbart att spara tid eller underlätta, utan även att öka effektiviteten och precisionen. Ju längre och mer komplext ett kommando är, desto svårare är det att komma ihåg och skriva korrekt. Fel kan vara av två slag: de som hindrar kommandot från att fungera och de som får det att utföra oväntade handlingar.
Kommandohistoriken eliminerar dessa problem. Som med många Linux-verktyg, finns det mer i detta än vad man först kan tro. Genom att lära dig hantera historikkommandot kan du förbättra din dagliga användning av Linux kommandorad. Det är en bra tidsinvestering. Det finns smartare sätt att använda historikfunktionen än att bara trycka på uppåtpilen gång på gång.
Använda history-kommandot
Enklast använder du kommandot history genom att skriva dess namn i terminalen:
history
Detta listar alla tidigare kommandon i terminalfönstret.
Kommandona är numrerade, med de senast använda kommandona (de med högsta numren) i slutet av listan.
För att visa ett specifikt antal kommandon, ange ett tal efter kommandot. Till exempel, för att se de senaste 10 kommandona skriver du:
history 10
Du kan uppnå samma sak genom att använda tail-kommandot i kombination med history:
history | tail -n 10
Återanvända kommandon
För att återanvända ett kommando från historiken, skriv ett utropstecken (!) följt av kommandots nummer, utan mellanslag.
För att till exempel upprepa kommando nummer 37 skriver du:
!37
För att upprepa det senaste kommandot, använd två utropstecken utan mellanslag:
!!
Detta är särskilt användbart om du glömde använda sudo i ett kommando. Skriv `sudo` följt av ett mellanslag och `!!` för att köra det senaste kommandot med administrativa rättigheter.
I följande exempel skrev vi ett kommando som kräver sudo. Istället för att skriva om hela raden kan vi spara tid genom att skriva `sudo !!`, som visas nedan:
mv ./my_script.sh /usr/local/bin/
sudo !!
Du kan använda kommandots nummer för att upprepa det eller använda dubbla utropstecken för att upprepa det senast körda kommandot. Men vad händer om du vill upprepa det femte eller åttonde kommandot bakåt i listan?
Du kan använda ett utropstecken, ett minustecken (-) och numret på ett tidigare kommando (igen utan mellanslag) för att upprepa det.
För att upprepa det trettonde kommandot bakåt i historiken, skriver du följande:
!-13
Söka efter kommandon via textsträng
För att upprepa det senaste kommandot som börjar med en viss sträng skriver du ett utropstecken följt av strängen (utan mellanslag) och trycker sedan på Enter.
För att exempelvis upprepa det senaste kommandot som började med `sudo` skriver du:
!sudo
Detta kan vara riskabelt. Om det senaste kommandot som började med `sudo` inte är det du förväntar dig, kommer du att köra fel kommando.
För att undvika detta kan du använda modifieraren `:p` (print), som visas nedan:
!sudo:p
Detta instruerar historiken att skriva ut kommandot i terminalen istället för att köra det direkt. På så vis kan du granska kommandot innan du använder det. Om det är kommandot du vill ha, tryck på uppåtpilen och sedan på Enter.
Om du vill hitta ett kommando som innehåller en viss sträng kan du använda ett utropstecken och frågetecken.
För att till exempel hitta och köra det första kommandot som innehåller ordet ”alias”, skriver du detta kommando:
!?aliases
Detta söker efter alla kommandon som innehåller strängen ”alias”, oavsett var i kommandot strängen förekommer.
Interaktiv sökning
En interaktiv sökning låter dig navigera genom en lista med matchande kommandon och återanvända det du vill ha.
Tryck bara på Ctrl+r för att starta sökningen.
När du skriver sökordet visas det första matchande kommandot. Bokstäverna du skriver visas mellan bakåtvända apostrofer (`) och vanliga apostrofer (’). De matchande kommandona uppdateras efterhand som du skriver varje bokstav.
Varje gång du trycker på Ctrl+r söker du bakåt efter nästa matchande kommando, som visas i terminalfönstret.
När du trycker på Enter kommer det visade kommandot att köras.
För att redigera ett kommando innan du kör det, tryck på vänster- eller högerpilen.
Kommandot visas då på kommandoraden där du kan redigera det.
Du kan även använda andra Linux-verktyg för att söka i historiklistan. Om du till exempel vill visa alla kommandon som innehåller strängen ”alias” kan du kombinera historik med grep, som så:
history | grep aliases
Ändra det senaste kommandot
Om du behöver korrigera ett stavfel och sedan upprepa kommandot kan du använda symbolen (^) för att ändra det. Detta är ett användbart trick om du stavat fel i ett kommando eller om du vill utföra ett kommando med en annan parameter.
Använd det genom att skriva (utan mellanslag): en symbol, texten du vill ersätta, en annan symbol, texten du vill sätta in och sedan en sista symbol, och tryck sedan på Retur.
Anta att du skrev följande kommando och råkat skriva ”shhd” istället för ”sshd”:
sudo systemctl start shhd
Du kan enkelt rätta till det genom att skriva följande:
^shhd^sshd^
Kommandot körs nu med ”shhd” korrigerat till ”sshd”.
Ta bort kommandon från historiken
Du kan också radera kommandon från historiken med alternativet -d (delete). Det finns ingen anledning att spara felstavade kommandon i historiken.
Du kan använda `grep` för att hitta det, ge dess nummer till history med -d alternativet och sedan söka igen för att verifiera att det är borta:
history | grep shhd
history -d 83
history | grep shhd
Du kan även skicka ett intervall av kommandon till alternativet -d. För att radera alla poster från 22 till 32 (inklusive), skriver du:
history -d 22 32
Om du vill ta bort de sista fem kommandona skriver du ett negativt tal, som så:
history -d -5
Manuell uppdatering av historikfilen
När du loggar in eller startar en terminalsession, laddas historiken in från historikfilen. I Bash är standardhistorikfilen `.bash_history`.
Eventuella ändringar du gör i din nuvarande terminalsession sparas inte i historikfilen förrän du stänger fönstret eller loggar ut.
Anta att du vill öppna ett annat terminalfönster för att komma åt hela historiken, inklusive kommandon du skrivit i det första terminalfönstret. Alternativet `-a` (alla) låter dig göra detta i det första fönstret innan du öppnar det andra.
För att använda det, skriv följande:
history -a
Kommandona sparas tyst i historikfilen.
Om du vill spara alla ändringar i historiklistan (till exempel om du raderat gamla kommandon) kan du använda alternativet `-w` (write) som så:
history -w
Rensa historiklistan
För att rensa alla kommandon från historiklistan kan du använda alternativet `-c` (clear) enligt följande:
history -c
Om du också vill tvinga fram dessa ändringar i historikfilen, använd alternativet -w, som så:
history -w
Säkerhet och historikfilen
Om du använder program som kräver att du skriver känslig information (som lösenord) på kommandoraden, kom ihåg att det också kommer att sparas i historikfilen. Om du vill undvika att viss information sparas kan du använda följande kommandostruktur för att omedelbart ta bort den från historiklistan:
special-app my-secret-password;history -d $(history 1)
history 5
Denna struktur innehåller två kommandon åtskilda av ett semikolon (;). Låt oss bryta ner det:
special-app
: Namnet på programmet vi använder.my-secret-password
: Det hemliga lösenordet vi behöver ange för programmet på kommandoraden. Detta avslutar kommando ett.history -d
: I kommando två anropar vi alternativet -d (radera) för `history`. Det vi ska ta bort kommer i nästa del av kommandot.$(history 1)
: Här används en kommandosubstitution. Den delen av kommandot som finns inom `$( )` körs i ett underskal. Resultatet av den körningen publiceras som text i det ursprungliga kommandot. Kommandot `history 1` returnerar det föregående kommandot. Så du kan se det andra kommandot som `history -d ”senaste kommandot här”`.
Du kan använda `history 5` för att verifiera att kommandot som innehöll lösenordet har tagits bort från historiken.
Det finns dock ett ännu enklare sätt. Eftersom Bash ignorerar rader som börjar med ett mellanslag, lägg bara till ett mellanslag i början av raden:
special-app another-password
history 5
Kommandot med lösenordet läggs inte till i historiklistan. Anledningen till att detta trick fungerar finns i `.bashrc`-filen.
.bashrc-filen
`.bashrc`-filen körs varje gång du loggar in eller öppnar ett terminalfönster. Den innehåller också några värden som styr historikkommandots beteende. Låt oss redigera filen med `gedit`.
Skriv följande:
gedit .bashrc
Nära toppen av filen ser du två inställningar:
HISTSTORLEK: Det maximala antalet poster som historiklistan kan innehålla.
HISTFILESIZE: Gränsen för antalet rader en historikfil kan innehålla.
Dessa två värden samverkar på följande sätt:
När du loggar in eller startar en terminalsession, laddas historiklistan från `.bash_history`-filen.
När du stänger ett terminalfönster, sparas det maximala antalet kommandon som anges i `HISTSIZE` i `.bash_history`-filen.
Om skal-alternativet `histappend` är aktiverat, läggs kommandona till `.bash_history`. Om `histappend` inte är inställt skrivs `.bash_history` över.
Efter att kommandona från historiklistan sparats till `.bash_history`, trunkeras historikfilen så att den inte innehåller fler än `HISTFILESIZE`-rader.
Även nära toppen av filen ser du en post för `HISTCONTROL`-värdet.
Du kan ange det här värdet för att göra något av följande:
ignorespaces
: Rader som börjar med ett mellanslag läggs inte till i historiklistan.ignoredups
: Duplicerade kommandon läggs inte till i historikfilen.ignoreboth
: Aktiverar båda ovanstående.
Du kan också lista specifika kommandon som du inte vill lägga till i din historiklista. Separera dessa med ett kolon (:) och sätt dem inom citationstecken (”…”).
Du kan lägga till en rad i `.bashrc`-filen enligt följande struktur och byta ut de kommandon du vill ignorera:
export HISTIGNORE="ls:history"
Använda tidsstämplar
Om du vill lägga till tidsstämplar till historiken kan du använda inställningen `HISTTIMEFORMAT`. För att göra det lägger du bara till en rad som följande i `.bashrc`-filen:
export HISTTIMEFORMAT="%c "
Notera att det finns ett mellanslag före det avslutande citationstecknet. Det förhindrar att tidsstämpeln hamnar direkt efter kommandot i listan.
Nu när du kör `history`-kommandot, visas datum och tid. Notera att alla kommandon som fanns i historiklistan innan du angav tidsstämplarna kommer att få tidsstämpel med datum och tid för det första kommandot som får en tidsstämpel. I exemplet nedan var det kommando 118.
Detta är en ganska lång tidsstämpel. Du kan använda andra värden än `%c` för att finjustera den. Andra värden du kan använda är:
%D
: Dagen%m
: Månaden%y
: Året%H
: Timmen%M
: Minuterna%S
: Sekunderna%F
: Fullständigt datum (format år-månad-dag)%T
: Tid (format timme:minut:sekund)%c
: Fullständigt datum och tidsstämpel (format dag-datum-månad-år och timme:minuter:sekunder)
Låt oss experimentera med några olika värden:
export HISTTIMEFORMAT="%d n%m %T "
Utskriften använder dag, månad och tid.
Om vi tar bort dagen och månaden kommer den bara visa tiden.
Alla ändringar du gör i `HISTIMEFORMAT` appliceras på hela historiklistan. Det är möjligt eftersom tiden för varje kommando lagras som antalet sekunder sedan Unix-epoken. Direktivet `HISTTIMEFORMAT` anger endast formatet som används för att återge det antalet sekunder i ett läsbart format, till exempel:
export HISTTIMEFORMAT="%T "
Vår produktion är nu mer hanterbar.
Du kan även använda historikkommandot för granskning. Genom att gå igenom tidigare kommandon kan du ibland hitta orsaken till ett problem.
Precis som i livet kan du i Linux använda historikkommandot för att återuppleva goda stunder och lära av misstagen.