
Toen ik gisteren echo $PATH typte om te zien hoe m’n path er uit zag schrok ik toch wel een beetje van de vele regels die over m’n scherm heen scrollde. Ik heb ze niet geteld, maar het waren er veel meer dan ik nodig acht.
Voor de mensen die niet zo bekend zijn met de commandline: in de variable PATH staan paden naar directories waar automatisch in gezocht wordt als je een bepaald commando typt. Een bekend commando is bijvoorbeeld cd wat gebruikt wordt om naar een andere directory te gaan. Dit kleine programma’tje staat in de directory /usr/bin. Doordat /usr/bin in het path staat kun je gewoon cd typen in plaats van elke keer volledig /usr/bin/cd te moeten typen.
In je path kun je meerdere directories opgeveven, gescheiden door een :, die één voor één doorzocht worden naar het ingetypte commando tot het commmando gevonden is.
Nu moet het voor de niet-zo-commandline-freakigere lezers ook duidelijk zijn dat ik het niet zo leuk vond dat dit path vele regels in beslag nam en dezelfde directories vaak terugkwamen waardoor het ook lastig was om uit te zoeken welke directory voorrang had.
Omdat ik toen toch wilde opruimen (en het is gelukt, het path is nu nog maar twee regels) heb ik gelijk heel mijn .profile maar eens goed doorgenomen en georganiseerd. En omdat ik vast niet de enige ben die bepaalde dingen uit mijn .profile kan gebruiken heb ik besloten het hier te delen.
Voor de mensen die ervaren zijn met de terminal en gewoon mijn .profile willen zien: download mijn .profile of ga direct naar de uitleg van de inhoud.
Andere mensen kunnen even rustig doorlezen om te zien wat .profile nu eigenlijk is en wat de inhoud in mijn geval doet.
En hoewel dit artikel is geschreven naar aanleiding van mijn ervaring op Mac OS X geldt dit natuurlijk ook gewoon voor Linux, BSD en andere systemen waarop bash in gebruik is.
Dus eh, .profile, wat is dat nou eigenlijk?
Waarschijnlijk zijn er inmiddels een aantal mensen die zich afvragen wat .profile nu eigenlijk is. Het is eigenlijk niet meer dan een simpel tekstbestand.
Maar zoals wel vaker in de UNIX-wereld is het wel een krachtig tekstbestand.
In dit bestand kun je namelijk commando’s plaatsen die worden uitgevoerd op het moment dat je inlogt op de terminal. Dit kan bijvoorbeeld iets zijn om het uiterlijk van je terminal aan te passen of om aliassen te maken voor commando’s die je veel gebruikt.
De rest van dit artikel zal praktische voorbeelden laten zien om te illustreren wat ik bedoel.
Eigenlijk zijn er een aantal verschillende bestanden die gebruikt worden om je terminal aan te passen. In het geval van bash hebben we het dan meestal over /etc/profile, /etc/bash.bashrc, ~/.bashrc, ~/.bash_profile en natuurlijk ~/.profile.
Deze hebben allemaal een eigen functie en roepen elkaar vaak aan, of ze overschrijven elkaar. Eigenlijk is het dan ook niet helemaal correct van mij om alles in ~/.profile te zetten, maar ik heb er niet zo’n probleem mee.
Voor de mensen die het wel graag 100% correct aanpakken is /etc/profile V.S. /etc/bashrc op LinuxQuestions.org waarschijnlijk interessant.
Hoe maak ik een .profile?
Je .profile plaats je in je home directory. Er is een goede kans dat je nog geen .profile hebt en dit bestand eerst moet aanmaken. Omdat het begint met een . is het een verborgen bestand, waardoor het misschien niet met elke editor te zien is. Wel kun je het aanmaken met iedere editor die gewoon platte tekst ondersteunt. Zelf gebruik ik meestal VI Improved (één van mijn favoriete editors, hier schrijf ik mogelijk later nog over) of Textmate.
Als je editor het opslaan van verborgen bestanden niet gemakkelijk ondersteunt kun je dit doen via een omweggetje:
- Maak het bestand aan en sla het op als profile.txt in je home directory;
- Start een terminal op (via Applications > Utilities > Terminal.app);
- Typ cd ~ om zeker te zijn dat je in je home directory zit;
- Typ mv profile.txt .profile;
- Klaar, je kunt nu weer de rest van de gewone stappen volgen.
Wijzigingen in je .profile worden pas zichtbaar nadat je opnieuw bent ingelogd of het volgende commando intypt: . ~/.profile.
En wat staat er nou in zo’n profile?
Het beruchte path
We beginnen met het beruchte path, wat bij mij nu netjes op twee regels staat en er zo uitziet:
export PATH=/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/local/sbin/:/usr/local/mysql/bin
export PATH=$PATH:/usr/bin:/bin:/usr/sbin/:/usr/local/sbin/:/sbin:/usr/X11R6/bin/:/Users/martijnengler/scripts/
Neem dit niet zomaar over, maar ik wil het even gebruiken als voorbeeld. Als ik nu dus bijvoorbeeld cd intyp wordt er eerst gezocht of er een programma met de naam cd in /opt/local/bin staat, vervolgens /opt/local/sbin, etc. .. Net zo lang tot het gevonden is. cd Staat overigens in /usr/bin. Als je je afvraagt waar een programma staat kun je dat bekijken met whereis.
Typ bijvoorbeeld whereis bash om te zien waar bash staat of whereis whereis om te zien waar whereis zelf staat.
Geschiedenis
De volgende paar regels bepalen hoe bash moet omgaan met de geschiedenis van ingetypte commando’s. Zelf kies ik er voor om mijn laatste 999 commando’s te bewaren zodat ik een uitgebreidde geschiedenis heb om door heen te gaan en herhaalde commando’s niet te laten zien. Dit doe ik met de volgende regels:
export HISTCONTROL=erasedups
export HISTFILESIZE=999
De eerste regel zorgt er voor dat commando’s die ik meerdere keren invoer maar één keer terugkomen in de geschiedenis. Laten we zeggen dat dit een reeks commando’s is die ik invoer:
cd /tmp
ps
vi
ps
top
vi
Als ik vervolgens met cursor-omhoog door mijn history loop zou ik normaal de commando’s in omgekeerd chronologische volgorde terugzien. Door het gebruik van erasedups zie ik: vi, top, ps, /tmp. Zowel vi als ps worden allebei dus één keer getoond in plaats van meerdere keren. Als je veel door je geschiedenis heen gaat is dit erg prettig.
Door de tweede regel heb ik een geschiedenis van 999 commando’s.
Het uiterlijk
Waar sommige mensen hun terminal op die van Lost willen laten lijken (zie ook deze reactie) ben ik meer voor een informatieve prompt met een lichte achtergrond.
Daarom kies ik voor de volgende regels in mijn bestand:
export CLICOLOR=1
export TERM=xterm-color
export LSCOLORS=ExFxCxDxBxegedabagacad
PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
De eerste drie regels zijn er om kleuren in te stellen. Als je liever een standaard zwart/wit hebt kun je dat dus gerust weglaten.
Het meest interessant is hier de laatste regel, deze bepaalt namelijk hoe je prompt er uit ziet. Op een Mac ziet de standaard opdrachtprompt er uit als hostname:dirnaam gebruikersnaam$ .
In mijn geval is dat bijvoorbeeld: puppis:ruby martijnengler$ als ik me in de directory ~/Documents/code/ruby bevind en ben ingelogd als martijnengler op mijn laptop, puppis.
Zelf zie ik echter liever het volledige path naar de directory waar ik me bevindt en mijn prompt ziet er dan ook zo uit: martijnengler@puppis:~/Documents/code/ruby$ .
Uiteraard zullen we allemaal onze eigen mening hebben hoe zo’n prompt er uit moet zien, daarom raad ik aan de documentatie van bash door te nemen om te zien welke variablen er allemaal beschikbaar zijn.
Een paar voorbeelden:
#volledige path naar de huidige directory
PS1='\w$ '
#computernaam:volledige path gebruikersnaam
PS1='\h:\w \u$ '
#voor de minimalisten: alleen een $
PS1='$ '
#een erg lange, als dat je ding is: de datum, tijd (HH:MM:SS in 24-uurs formaat) username@hostname : het volledige path naar de huidige directory
PS1='\d \t \u@\H : \w$'
#dezelfde lange prompt als net, nu verdeeld over twee regels
PS1='\d \t\n\u@\H : \w$'
Alles eindigt met een $, dit is gebruikelijk als je bent ingelogd als een “normale” user. Een # wordt gebruikt bij root (de beheerder van de computer) om zo snel te kunnen zien als wat voor user je bent ingelogd.
Uiteraard zijn er vele variaties te bedenken, expirimenteer hiermee totdat je iets hebt gevonden wat goed werkt voor jou. Een volledig overzicht van de variablen is beschikbaar in de handleiding.
Aanvullen van commands
Men zegt altijd “een goede ICT-er is lui”, waarmee bedoelt wordt dat ICT-ers graag zo min mogelijk doen om zoveel mogelijk werk klaar te krijgen. Wat daar bij helpt is het aanvullen van commando’s door slecht een paar karakters te typen en dan op tab te drukken.
Omdat ik ook een (goede) ICT-er ben heb ik dan ook de volgende regels opgenomen:
set show-all-if-ambiguous On
bind "set completion-ignore-case on"
complete -A user su sudo
complete -A hostname rsh rcp telnet rlogin r ftp ping disk ssh
Deze regels zorgen er voor dat:
- Alle mogelijke commands getoond worden als er meerdere mogelijkheden zijn. Typ ik bijvoorbeeld cl[tab] krijg ik
cleanlinks, clear en clri te zien;
- Het aanvullen niet hoofdlettergevoelig is, wat erg handig is als je niet zeker bent over het hoofdlettergebruik;
- Usernames worden aangevuld na de commando’s
su en sudo;
- Hostnames (zoals gevonden in /etc/hosts) worden aangevuld na het intypen van bijvoorbeeld
ftp of ssh.
Aliassen
Hoewel het aanvullen van commando’s erg handig is, is het soms handiger om gewoon een korte alias te hebben voor een lang commando wat verschillende parameters accepteert. Gelukkig kan dit ook met alias aliasnaam commando in de file. Hieronder mijn aliassen:
alias ll='ls -hlA'
alias irb='irb -r irb/completion'
alias cp='cp -i'
alias mv='mv -i'
alias st="svn st -u"
alias chi="svn ci *"
alias up="svn up"
alias di="svn diff"
alias rv="svn revert"
alias profileme="history | awk '{print \$2}' | awk 'BEGIN{FS=\"|\"}{print \$1}' | sort | uniq -c | sort -n | tail -n 20 | sort -nr"
alias e=mate
alias grip="grep -i"
alias sthrn="ruby /Users/martijnengler/code/ror/hrn/script/server webrick -p 3002"
#... zo nog een aantal voor RoR
Op deze manier kan door het typen van ll een lijst met bestanden in de directory krijgen, onder elkaar, met leesbare groottes (in kilobytes, megabytes, gigabytes etc.) inclusief verborgen bestanden. Als ik altijd het volledige ls -hlA zou moeten typen zou ik dit handige commando veel minder gebruiken.
De alias voor irb heb ik al eerder over geschreven, dit zorgt voor tab completion in de Interactive RuBy shell.
Ook de commando’s cp en mv overschrijf ik. Op deze manier komt er een prompt als je op het punt staat een file te overschrijven, net als in Mac OS X of Windows. Dit voorkomt het per ongeluk overschrijven van files.
De aliassen voor svn zijn handig voor mensen die hiermee werken. Deze hebben geen uitleg nodig voor SVN-gebruikers en zijn niet interessant voor mensen die dit toch niet gebruiken.
De profileme-alias werkt niet samen met export HISTCONTROL=erasedups, maar geeft anders wat statistieken over de commando’s die je gebruikt. Best grappig dus, als je erasedups niet gebruikt.
e=mate maakt het commando om Textmate te openen nog korter. Vaak zit ik in een directory en wil ik die openen als project in Textmate om er aan te gaan werken. Ik typ dan simpelweg e . om te beginnen.
De grip-alias is een kortere manier om een grep uit te voeren die niet hoofdlettergevoelig is. Je kunt eventueel ook de alias grep noemen als je grep nooit hoofdlettergevoelig wilt gebruiken.
De laatste alias, sthrn, he ik er een aantal van. Hiermee kan ik snel een Rails-server starten zonder het hele path te moeten kennen, te weten op welke poort ik het wil draaien en expliciet aan te geven dat ik webrick wil gebruiken in plaats van Mongrel.
Overig
En dan zijn er nog wat dingetjes die ik gewoon graag neerzet:
export EDITOR=vi
export LC_CTYPE=en_US.UTF-8
export set CLASSPATH=/usr/local/lib/mysql/mysql-connector-java.jar:.
export RUBYOPT=rubygems
set -o vi
set bell-style none
Dit maakt vi de standaard editor, zet de encoding op UTF-8, voegt de MySQL-connector toe aan mijn classpath voor Java, zorgt er voor dat rubygems automatisch geladen worden en maakt vi ook de editor die gebruikt wordt op de commandline zelf. En natuurlijk schakelen we die irritante beep uit…
Wil je ook alles hebben? Download mijn .profile!
Een makkelijke en snelle manier om dat te doen is door dit in te typen op de terminal: cd ~; curl -o .profile http://digicted.nl/uploads/.profile; . .profile
Dit verandert de huidige directory naar je homedirectory, download de .profile van Digicted en activeert ‘m.
Vragen, tips of opmerkingen?
Als altijd: de reacties staan open, want ik ben voor open communicatie. Behalve spam worden reacties nooit in de prullenbak gegooid.
Toch raad ik aan eventuele liefdesbrieven of huwelijksaanzoeken via email te doen of anoniem te posten. Uiteraard ben je hier echter ook vrij in, dus post ze gerust in de comments.