HOWTO: Bash terminal in Mac OS X afstellen
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,clearenclrite 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
suensudo; - Hostnames (zoals gevonden in /etc/hosts) worden aangevuld na het intypen van bijvoorbeeld
ftpofssh.
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.

11-11-2007 17:22
[...] Zet dit in je .profile: [...]
29-01-2008 11:42
Dag
Omdat jij een goed verhaal hebt over terminal kun je me misshcien helpen. Ik ben de webmaster van st de navigators en we zijn bezig met een nwe website, en tegelijkertijd moeten onze sites verhuist worden naar een andere server. Ik heb alle bestanden overgezet en wil ze nu testen, maar onze provider kan me niet vertellen hoe ik dat op de mac kan doen. Ik heb ondertussen wel gevonden dat het hosts bestand op de mac bij terminal staat en dat ik daar wsch iets kan aanpassen maar ik weet neit hoe dat werkt. Kunt u mij helpen? Op het internet kan ik er eigenlijk ook nauwelijks iets over vinden. Het zou mij enorm helpen
alvast mijn hartelijke dank.
29-01-2008 12:24
Marieke, naar ik begrijp staan je bestanden op een nieuwe server (met een nieuw IP) en wil je nu dus dat navigators.nl wijst naar dat nieuwe IP-adres op jouw lokale PC?
Dat is erg gemakkelijk te doen op de Mac met de volgende commando’s:
1) Start terminal op
2) Typ sudo open -e /etc/hosts
3) Voer je wachtwoord in
4) Je editor zal openen, voeg onderaan het bestand de volgende regel toe:
1.1.1.1 navigators.nl*5) Sla het bestand op.
6) Terug in de terminal typ je: dscacheutil -flushcache
7) Typ ping navigators.nl op de terminal, controleer of het juiste IP-adres genoemd wordt. Druk op ctrl+c.
Als je nu naar de site toegaat wordt het nieuwe IP-adres gebruikt.
Als je de instellingen weer terug wilt zetten zoals ze waren voer je gewoon weer alle stappen uit, maar nu verwijder je de regel uit je hosts-bestand bij stap 4.
*) Bij stap 4 dien je in plaats van 1.1.1.1 het nieuwe ip-adres uiteraard in te vullen!
Heb je verder nog vragen? Reageer dan gerust hieronder of stuur me een email.
02-03-2008 14:21
Hi goed stukje! Heb nog even wat eigen ervaringen:
.profile wordt pas gelezen als .bashrc en .bash_profile weg zijn,
.bashrc is in mijn ervaring de enige file wordt gelezen met een interactive shell (in mijn geval shell vanuit emacs, waar jij als vi gebruiker wellicht geen boodschap aan hebt), en .bash_profile vanuit de terminal.
Ik ben op zich wel benieuwd naar de precieze werking hiervan dus als je dat nog eens zou kunnen vermelden??
om verwarring te voorkomen heb ik mijn .bash_profile aangepast:
if [ -f ~/.bashrc ]; then
source ~/.bashrc
fi
# http://www.joshstaiger.org/archives/2005/07/bash_profile_vs.html
zodat terminal en emacs shell gelijke paramaters hebben.
Jeroen.
04-03-2008 17:47
Hoi Jeroen,
Bedankt!
Zoals in het stukje vermeld staat weet ik het ook niet exact. Op veel van m’n Unix-bakken gebruik ik inderdaad ook zoiets als jij in je .bash_profile hebt.
In vim is het wel zo dat je er niet zo’n last van hebt als in emacs, hoewel ik geen vim-expert ben.
Zoals gezegd, lees http://www.linuxquestions.org/questions/linux-general-1/etcprofile-v.s.-etcbashrc-273992/
eens door voor een goede uitleg.
De link die je zelf geeft, geeft ook juiste informatie lijkt me.
- Martijn
02-07-2008 19:45
Hoi Martijn,
Knap stukje info.
Ik kom hier als echte leek binnen en heb vandaag voor het eerst Terminal geopend doordat ik op deze site kwam: http://www.macworld.com/article/131094/2007/12/screensharepower.html
Mijn bedoeling was om wat te testen omtrent schermdelen in leopard.
Nu heb ik het idee dat ik wat teveel codes heb ingevuld en besef nu dat dit een krachtig script is wat al werkt zonder het te hoeven opslaan.
Kan ik mijn script nog verwijderen en waar kan ik uberhaupt deze script terug vinden.
mvg Corné
02-07-2008 20:17
Beste Corné,
Bedankt !
Wat betreft je probleem: als je alleen dit regeltje code hebt uitgevoerd:
defaults write com.apple.ScreenSharing ShowBonjourBrowser_Debug 1
Is het simpel. Type in de terminal:
defaults write com.apple.ScreenSharing ShowBonjourBrowser_Debug 0
Voor het tweede stuk code moet je waarschijnlijk een plist gaan bewerken. Iets waar ik je graag mee help, als je me kunt laten weten of dat nog nodig is.
Succes,
Martijn
17-02-2010 14:45
verhelderend stukje! thanks for sharing!!!