Skript som gör alias av senaste kommando…
- Johnny Rosenberg
- Inlägg: 1256
- Blev medlem: 23 jun 2007, 16:18
- OS: Ubuntu
- Utgåva: 22.10 Kinetic Kudu
- Kontakt:
Skript som gör alias av senaste kommando…
Hade en idé om att göra ett enkelt skript (bash) som gör följande:
Plockar fram senaste kommandot (eller näst senaste, eftersom det senaste förmodligen är körandet av själva skriptet) från ~/.bash_history, gör ett alias av det och placerar alias-kommandot sist i filen ~/.bash-aliases – en fil som jag anropar från ~/.bashrc.
Men jag stötte på patrull efter patrull.
Först upptäckte jag att kommandot history inte funkar i ett skript; det returnerar ingenting då.
Okej, inga problem, jag tittar istället direkt i ~/.bash_history. Nehej, det gick inte, för den är sällan aktuell; det fattas oftast några tiotal rader där, så det verkar som att den samlar på sig kommandon och lägger in dem klumpvis i filen.
Men okej, det gick tydligen att åtgärda genom att skriva några väl valda rader i sin ~/.bashrc-fil, men det känns ju lite ”så där” att man ska behöva ha sitt system specialkonfigurerat för att ett visst skript ska fungera.
Så fick jag en annan idé, nämligen att användaren själv kan mata in senaste kommandot som argument till skriptet. Låter ju jobbigt, men det är ju väldigt enkelt tack vare ”!!” som ju expanderas till senaste kommandot automatiskt.
Jaha ja, vad bra, då. Så jag börjar skriva på lite i all min okunnighet, men stöter åter på patrull.
Lättast att visa med ett exempel.
Jag kanske vill göra ett alias för att ta mig till en speciell mapp som ligger ett antal nivåer neråt. Manuellt kanske man skriver:
cd "/home/jag/min fina/mapp som tar/en stund/att/skriva/sökvägen till"
Man kan givetvis också skriva:
cd /home/jag/min\ fina/mapp\ som\ tar/en\ stund/att/skriva/sökvägen\ till
Problemet är ju att om man väljer första skrivsättet så förvinner citat-tecknen och om man väljer andra skrivsättet så försvinner bakåtsnedstrecken när väl texten tagits in till skriptet i form av argument eller parametrar eller vad man kallar det!
Jag kom inte på något enkelt sätt att komma runt detta, i alla fall inte om användaren ska förväntas kunna mata in i princip vad som helst.
Är det bara ”cd sökväg” som väntas är det ju enkelt att låta skriptet ”manuellt” placera ut dubbelfnuttarna på rätt ställen, men det är kanske inte så ofta som det är så enkelt.
Någon som har några idéer?
Så här hade jag tänk mig att det hela skulle fungera:
Användaren kör ett kommando och kommer på att han vill ha det som ett alias, eftersom han kommer att utföra det ganska ofta. Det kan vara vad som helst, men låt oss hålla oss till det enkla:
cd "/home/jag/min fina/mapp som tar/en stund/att/skriva/sökvägen till"
Ett skript som heter ”pa” (permanent alias…) ska fixa biffen om man kör det direkt efter föregående kommando:
pa xyz !!
Bash expanderar detta till:
pa xyz cd "/home/jag/min fina/mapp som tar/en stund/att/skriva/sökvägen till"
Skriptet ska sedan sätta ihop detta till ett alias-kommando:
alias xyz='cd "/home/jag/min fina/mapp som tar/en stund/att/skriva/sökvägen till"' som sedan ska läggas på slutet av ~/.bash-aliases, så att aliaset kommer att fungera permanent.
Istället blir det:
alias xyz='cd /home/jag/min fina/mapp som tar/en stund/att/skriva/sökvägen till'
vilket inte leder längre än till ett felmeddelande, eftersom mellanslagen tjänstgör som separator mellan parametrar till cd-kommandot.
Någon som kommer på något enkelt sätt att komma runt detta lilla mini-problem? Förutom att användaren själv skriver ”\\” istället för ”\” eller ”\"” istället för ”"”, förstås…
Visst kan man analysera varje ord och lista ut vad som är sökvägar och inte, men det känns som ett lite större projekt än vad jag hade tänkt mig, vilket enbart kommer att resultera i att det rinner ut i sanden.
Funderar också på om det blir annorlunda om jag väljer att göra det i C istället (mest på grund av att jag inte kan något annat, och knappt det ens), men jag misstänker att det inte spelar någon roll.
Som sagt, idéer är välkomna.
Plockar fram senaste kommandot (eller näst senaste, eftersom det senaste förmodligen är körandet av själva skriptet) från ~/.bash_history, gör ett alias av det och placerar alias-kommandot sist i filen ~/.bash-aliases – en fil som jag anropar från ~/.bashrc.
Men jag stötte på patrull efter patrull.
Först upptäckte jag att kommandot history inte funkar i ett skript; det returnerar ingenting då.
Okej, inga problem, jag tittar istället direkt i ~/.bash_history. Nehej, det gick inte, för den är sällan aktuell; det fattas oftast några tiotal rader där, så det verkar som att den samlar på sig kommandon och lägger in dem klumpvis i filen.
Men okej, det gick tydligen att åtgärda genom att skriva några väl valda rader i sin ~/.bashrc-fil, men det känns ju lite ”så där” att man ska behöva ha sitt system specialkonfigurerat för att ett visst skript ska fungera.
Så fick jag en annan idé, nämligen att användaren själv kan mata in senaste kommandot som argument till skriptet. Låter ju jobbigt, men det är ju väldigt enkelt tack vare ”!!” som ju expanderas till senaste kommandot automatiskt.
Jaha ja, vad bra, då. Så jag börjar skriva på lite i all min okunnighet, men stöter åter på patrull.
Lättast att visa med ett exempel.
Jag kanske vill göra ett alias för att ta mig till en speciell mapp som ligger ett antal nivåer neråt. Manuellt kanske man skriver:
cd "/home/jag/min fina/mapp som tar/en stund/att/skriva/sökvägen till"
Man kan givetvis också skriva:
cd /home/jag/min\ fina/mapp\ som\ tar/en\ stund/att/skriva/sökvägen\ till
Problemet är ju att om man väljer första skrivsättet så förvinner citat-tecknen och om man väljer andra skrivsättet så försvinner bakåtsnedstrecken när väl texten tagits in till skriptet i form av argument eller parametrar eller vad man kallar det!
Jag kom inte på något enkelt sätt att komma runt detta, i alla fall inte om användaren ska förväntas kunna mata in i princip vad som helst.
Är det bara ”cd sökväg” som väntas är det ju enkelt att låta skriptet ”manuellt” placera ut dubbelfnuttarna på rätt ställen, men det är kanske inte så ofta som det är så enkelt.
Någon som har några idéer?
Så här hade jag tänk mig att det hela skulle fungera:
Användaren kör ett kommando och kommer på att han vill ha det som ett alias, eftersom han kommer att utföra det ganska ofta. Det kan vara vad som helst, men låt oss hålla oss till det enkla:
cd "/home/jag/min fina/mapp som tar/en stund/att/skriva/sökvägen till"
Ett skript som heter ”pa” (permanent alias…) ska fixa biffen om man kör det direkt efter föregående kommando:
pa xyz !!
Bash expanderar detta till:
pa xyz cd "/home/jag/min fina/mapp som tar/en stund/att/skriva/sökvägen till"
Skriptet ska sedan sätta ihop detta till ett alias-kommando:
alias xyz='cd "/home/jag/min fina/mapp som tar/en stund/att/skriva/sökvägen till"' som sedan ska läggas på slutet av ~/.bash-aliases, så att aliaset kommer att fungera permanent.
Istället blir det:
alias xyz='cd /home/jag/min fina/mapp som tar/en stund/att/skriva/sökvägen till'
vilket inte leder längre än till ett felmeddelande, eftersom mellanslagen tjänstgör som separator mellan parametrar till cd-kommandot.
Någon som kommer på något enkelt sätt att komma runt detta lilla mini-problem? Förutom att användaren själv skriver ”\\” istället för ”\” eller ”\"” istället för ”"”, förstås…
Visst kan man analysera varje ord och lista ut vad som är sökvägar och inte, men det känns som ett lite större projekt än vad jag hade tänkt mig, vilket enbart kommer att resultera i att det rinner ut i sanden.
Funderar också på om det blir annorlunda om jag väljer att göra det i C istället (mest på grund av att jag inte kan något annat, och knappt det ens), men jag misstänker att det inte spelar någon roll.
Som sagt, idéer är välkomna.
- mcNisse
- Inlägg: 5211
- Blev medlem: 06 feb 2007, 20:51
- OS: Debian
- Utgåva: Vet inte/ingen utgåva passar
Re: Skript som gör alias av senaste kommando…
Du kan köra pa med "!!" så får du hela uttrycket som ett argument istället för flera (i bästa fall, se exemplet). Det gör att skriptet fungerar med \. Dock inte när man använder fnuttar.
Som du ser kvaddas funtionaliteten av fnuttar. Då blir det inte längre ett argument utan flera.
Kod: Markera allt
pa() {
echo "alias $1='$2'"
}
#backslash
echo hej\ hopp
pa hp "!!"
==>
pa hp "echo hej\ hopp"
alias hp='echo hej\ hopp
#fnuttar
echo "hej hopp"
pa hp "!!"
==>
pa hp "echo "hej hopp""
alias hp='echo hej'
- Johnny Rosenberg
- Inlägg: 1256
- Blev medlem: 23 jun 2007, 16:18
- OS: Ubuntu
- Utgåva: 22.10 Kinetic Kudu
- Kontakt:
Re: Skript som gör alias av senaste kommando…
Okej, det är ju ett sätt att komma runt det hela lite med bara två extra tangentnedtryckningar. Får väl anses vara acceptabelt.mcNisse skrev:Du kan köra pa med "!!" så får du hela uttrycket som ett argument istället för flera (i bästa fall, se exemplet). Det gör att skriptet fungerar med \. Dock inte när man använder fnuttar.
Som du ser kvaddas funtionaliteten av fnuttar. Då blir det inte längre ett argument utan flera.Kod: Markera allt
pa() { echo "alias $1='$2'" } #backslash echo hej\ hopp pa hp "!!" ==> pa hp "echo hej\ hopp" alias hp='echo hej\ hopp #fnuttar echo "hej hopp" pa hp "!!" ==> pa hp "echo "hej hopp"" alias hp='echo hej'
Funderar på om det kunde fungera med enkelfnuttar?
pa hp '!!'
Ska strax åka till jobbet så jag hinner inte testa nu.
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
Re: Skript som gör alias av senaste kommando…
Det är inte lämpligt att använda ~/.bash_history för sånt här eftersom den inte alltid är helt uppdaterad. Det kan dessutom uppstå konflikter om du har flera olika terminaler igång samtidigt. Då är det bättre att använda den interna historielistan istället (se help history för mer info).Johnny Rosenberg skrev:Hade en idé om att göra ett enkelt skript (bash) som gör följande:
Plockar fram senaste kommandot (eller näst senaste, eftersom det senaste förmodligen är körandet av själva skriptet) från ~/.bash_history,
Det är faktiskt inte möjligt att göra alias av allt som kan tänkas finnas i historielistan. Då är det bättre att använda skalfunktioner så undviker du smidigt alla de begränsningar som alias har.Johnny Rosenberg skrev:gör ett alias av det och placerar alias-kommandot sist i filen ~/.bash-aliases – en fil som jag anropar från ~/.bashrc.
Du bör inte använda dig av ett separat skript i det här fallet. Använd en skalfunktion istället så kommer du enkelt åt historielistan. Om du av någon anledning verkligen vill ha ett separat skript så måste du läsa in det med kommandot source istället för att köra det som vanligt.Johnny Rosenberg skrev:Men jag stötte på patrull efter patrull.
Först upptäckte jag att kommandot history inte funkar i ett skript; det returnerar ingenting då.
Mitt förslag är som sagt att du använder skalfunktioner istället för skript och alias. Det skulle kunna se ut ungefär så här:Johnny Rosenberg skrev:Någon som har några idéer?
Så här hade jag tänk mig att det hela skulle fungera:
Användaren kör ett kommando och kommer på att han vill ha det som ett alias, eftersom han kommer att utföra det ganska ofta. Det kan vara vad som helst, men låt oss hålla oss till det enkla:
cd "/home/jag/min fina/mapp som tar/en stund/att/skriva/sökvägen till"
Ett skript som heter ”pa” (permanent alias…) ska fixa biffen om man kör det direkt efter föregående kommando:
pa xyz !!
Bash expanderar detta till:
pa xyz cd "/home/jag/min fina/mapp som tar/en stund/att/skriva/sökvägen till"
Skriptet ska sedan sätta ihop detta till ett alias-kommando:
alias xyz='cd "/home/jag/min fina/mapp som tar/en stund/att/skriva/sökvägen till"' som sedan ska läggas på slutet av ~/.bash-aliases, så att aliaset kommer att fungera permanent.
Kod: Markera allt
pa(){
eval function $(printf '%q(){' "$1") "$(fc -ln -1 && echo \})" &&
declare -f "$1" | tee -a ~/.bash-aliases
}
Jag tyckte att det kunde vara vettigt att få se vad som just har lagts till. Om du inte vill ha sådan utdata så kan du byta ut
| tee -a mot >> istället.
- mcNisse
- Inlägg: 5211
- Blev medlem: 06 feb 2007, 20:51
- OS: Debian
- Utgåva: Vet inte/ingen utgåva passar
Re: Skript som gör alias av senaste kommando…
Snyggt och lärorikt!!! fc och declare kände jag inte till.Konservburk skrev:Mitt förslag är som sagt att du använder skalfunktioner istället för skript och alias. Det skulle kunna se ut ungefär så här:Kod: Markera allt
pa(){ eval function $(printf '%q(){' "$1") "$(fc -ln -1 && echo \})" && declare -f "$1" | tee -a ~/.bash-aliases}
- Johnny Rosenberg
- Inlägg: 1256
- Blev medlem: 23 jun 2007, 16:18
- OS: Ubuntu
- Utgåva: 22.10 Kinetic Kudu
- Kontakt:
Re: Skript som gör alias av senaste kommando…
Jisses – jag trodde mitt problem var i det närmaste omöjligt att lösa. Är övertygad om att jag aldrig hade kunnat få ett sådant här svar från Ubuntu-mail-listan. Imponerande.Konservburk skrev:Det skulle kunna se ut ungefär så här:
Lägg in detta i ~/.bashrc (eller motsvarande). Då kan du köra pa xyz för att automatiskt skapa en skalfunktion xyz av kommandot som kördes i samma terminal precis innan (som hamnar i slutet av ~/.bash-aliases).Kod: Markera allt
pa(){ eval function $(printf '%q(){' "$1") "$(fc -ln -1 && echo \})" && declare -f "$1" | tee -a ~/.bash-aliases }
Jag tyckte att det kunde vara vettigt att få se vad som just har lagts till. Om du inte vill ha sådan utdata så kan du byta ut
| tee -a mot >> istället.
Idag lärde jag mig något nytt, tackar för det!