Des Astuces shell pour MAC/OSX mais valables pour UNIX et LINUX.
Grand merci à KLAUS !
à la page précédente.
TABLE des MATIÈRES :Commandes utiles
Planification 2
Utilitaires Internet
Utilitaires Internet 2
Asuces Shell 2
Tuer !
Astuces Apache
Les commandes intégrées au Shell
Démarrage du Shell 'tcsh'
'find' et 'xargs'
L'Editeur de Texte Vim
Comment faire pour...?
Comment faire pour...?
L'Editeur de Texte Vim - II
tcsh vs sh/bash
Gérer les fichiers tenaces
Astuces sur le Scripting
Liens at Alias (6 Octobre
Astuces d'Edition
Expressions Régulières POSIX
Expressions Régulières POSIX II
Logging
Gestion Avancée du Logging
ftp (1
ntenance Périodique
Astuces de Scripting du Bash
Astuces Bash
La commande 'open'
Extension des Paramètres Bash
Editeur Vim III - Rechercher
Type de Fichier de part son Contenu
Personnalisation du Shell Bash
Documents Céans sous Bash
Scripts Utiles
Le Terminal de Panther
Commandes plutôt cool
Tirer le Meilleur de Bash - I
Tirer le meilleur de Bash - II
Elle Vend des Sous-shell Entre Parenthèses
NetInfo
Signaux et Trappes
Contrôle des Tâches
Conditions sous Bash
Guillemets et Apostrophes sous Bash
Montages AFP et NFS
L'Editeur de Flux sed
Le Processeur Awk
Awk Avancé
ntenance Fichiers
Comportements Bizarres dans...
Comptes Utilisateur
Astuces de Script Bash III
Astuces de Script Bash IV
Régler FTP
Quelques Commandes Utiles
Comptes Utilisateur II
Trouve
Espaces dans les Noms de Fichier
Astuces Terminal
En Cas de Problèmes
Référence des Commandes Unix
Référence des Commandes Unix II
Référence des Commandes Unix III
Référence des Commandes Unix IV
Contrôler Bash au Démarrage
Nouveautés de Tiger
Séparater les composants d'un nom de fichier
Utilisez la technique suivante dans des scripts tsch pour extraire d'une variable ou d'un paramètre les composants d'un chemin d'accès complet à un fichier.
Le chemin d'accès complet :
% echo $fnExtrayez le chemin d'accès (en-tête) :
% echo $fn:hExtrayez le nom de fichier (queue):
% echo $fn:tExtrayez l'extension :
% echo $fn:eRetirez l'extension :
% echo $fn:r Séparer les composants d'un nom de fichier II
Suite de l'astuce de Lundi, les modifieurs ':' peuvent être combinés. Pour juste extraire le nom de fichier sans l'extension, combinez t et r :
% echo $fnVous pouvez changer un nom de fichier en utilisant une substitution :
% echo $fn
Mac OS X n'a pas de commande permettant de renommer plusieurs fichiers. Utilisez les techniques de Lundi et de Mardi pour écrire un script qui le fera.
% cat renameAjoutez la commande 'find' des semaines 1 et 13 pour renommer en mode batch (arrière-plan) :
% ls Extraction sur la Ligne de Commande
Les techniques de Lundi et Mardi peuvent être appliquées aux commandes tcsh tapées sur la ligne de commande. En particuliers, elles peuvent être combinées avec l'astuce du Vendredi de la semaine 29 :
% ls *.htmlet
% ls *.htmJe vous laisserai deviner ce qui va arriver.
Les commandes basename et dirname extraient les parties respectives d'un nom de chemin complet. Ce sont des commandes et elles peuvent donc être utilisées dans n'importe quel script, au contraire des astuces du début de la semaine qui sont spécifiques à tcsh.
% echo $fn
Certaines personnes ont quelques fois besoin d'appliquer la même commande à plusieurs fichiers et l'utilisation de 'find' est une bonne approche. Vous pouvez écrire le script suivant pour rendre la chose plus simple.
% cat xfind
#!/bin/sh if [ "$1" = " ]; then echo "Usage: `basename $0` filetype [command to -exec]" exit fi
if [ "$2" = " ]; then find . -name "$1" else find . -name "$1" -exec $2 {} ; fi
Ce script est écrit en /bin/sh, plutôt qu'en /bin/tcsh. N'oubliez pas de rendre le fichier script exécutable.
% xfind "*.html"va lister tous les fichiers correspondants du répertoire courant et des sous-répertoires.
% xfind "*.html" lessva les afficher.
Voici un script pour changer un fichier comportant des caractères de fin de ligne traditionnels Mac en un fichier comportant des fins de lignes Unix.
% cat unix2mac
#!/bin/sh
if [ "$1" = " ]; then echo "Usage: `basename $0` filename" exit fi
tr \r \n < $1 > $1.tmp ; mv $1.tmp $1
Ce script peut être combiné avec le script xfind de Lundi :
% xfind "*.html" unix2mac
Pour compléter le script de Mardi, voici l'opération inverse :
% cat mac2unix #!/bin/sh
if [ "$1" = " ]; then echo "Usage: `basename $0` filename" exit fi
tr \n \r < $1 > $1.tmp ; mv $1.tmp $1
Voici un script pour renommer des fichiers dans le répertoire courant. Il peut être adapté pour effectuer d'autres fonctions.
% cat rename
#!/bin/sh #Je vous laisserai le soin de tester les erreurs...
for fn in *.$1 do mv $fn `basename $fn $1`$2 done
La commande :
% rename txt rtfva changer *.txt en *.rtf dans le répertoire courant.
N'oubliez pas que quand vous insérez une commande dans des apostrophes, vous pouvez utiliser ses sorties comme des arguments pour une autre commande.
Par exemple, pour éditer tous les fichiers html dans un répertoire et ses sous-répertoires (en utilisant le script 'xfind' de lundi) :
% vi `xfind "*.html"`(ou vim, emacs, pico, bbedit...)
La commande Unix 'at' peut être utilisée pour executer une commande donnée à une heure donnée. (Mais pas à une date donnée dans OS X). Toutefois, quelques modifications doivent être faites à OS X avant que ce ne soit possible. Celles-ci doivent être faites en tant que root.
1. Enlevez les signes de commentaires (les #) dans la ligne suivante qui est dans /etc/crontab:
#*/5 * * * * root /usr/libexec/atrunpour vérifier les jobs 'at' en attente toutes les 5 minutes.
2. Créez le répertoire suivant s'il n'existe pas encore :
sudo mkdir /var/at/spool3. Créez un fichier 'deny' vide pour permettre à tous les utilisateurs d'utiliser 'at'
sudo touch /var/at/at.deny(Ou créez 'at.allow' et ajoutez une liste des utilisateurs ayant l'autorisation.)
(Voir la semaine 33 pour plus de commandes de planification.)
Utilisez la commande 'at' pour programmer une (suite de) commande(s) à executer plus tard. L'exemple suivant programme le déclenchement de l'application Horloge à 21:30 aujourd'hui. Les commandes à exécuter peuvent être directement fournies sur la ligne de commande, ou lues d'un fichier avec l'option '-f'.
% cat at-fileA 21:30, l'application Horloge de OS X sera lancée.
Il est possible d'examiner la liste des jobs dans la queue 'at' de l'utilisateur du moment avec :
% atq Date Owner Queue Job# 21:26:00 04/20/03 saruman a a010b400a.000
et effacer des jobs avec :
% atrm a010b400a.000en donnant le numéro du job qui est plutôt vilain.
Quand la liste des commandes donnée par 'at' est éxécutée, elle l'est par le shell /bin/sh. Les variables d'environnement et le répertoire actuel sont recréés pour correspondre à ceux qui existaient quand la commande 'at a été lancée.
Si des commandes doivent se reporter à votre répertoire de base, utilisez :
$HOMELe temps peut être spécifié par rapport à l'instant présent avec :
at -f at-file now + 10 minutes
Utilisez la commande 'calendar' pour prévoir des rendez-vous et des évènements. Créez un fichier texte (nom par défaut 'calendar') contenant un mois, une date et un évènement sur chaque ligne.
% cat calendarAffichez les évènements pour une date donnée (spécifiée comme MMJJ) avec les commandes suivantes :
% calendar -d 0410Pour aujourd'hui (le 20 avril dans cet exemple), vous pouvez vous passer de préciser la date :
% calendarSi le fichier n'est pas 'calendar' dans le répertoire actuel, utilisez l'option '-f' :
% calendar -f /path/name/file-name -d 0429Unix a des fichiers de calendrier déjà prêts dans :
/usr/share/calendarPar exemple :
% calendar -f /usr/share/calendar/calendar.holiday -d 0421 04/21 San Jacinto Day in Texas 04/22 Arbor Day in Nebraska & Delaware 04/22 Oklahoma Day in Oklahoma 04/21 Tiradentes in Brazil
Nous connaissons tous le vénérable utilitaire 'ping'.
- il peut vérifier si une machine est active
- il peut vérifier si votre connexion réseau est en bon état
- il peut faire un bilan de la réactivité générale de tout ce qui se dirige vers une machine particulière (le champ 'time=')
- il peut trouver l'adresse IP d'une machine
Par exemple :
% ping apple.comL'option '-i' peut être utilisée pour changer l'intervalle entre les envois de ping, et l'option '-c' peut être utilisée pour envoyer un nombre spécifié de pings. Par exemple, pour faire un ping à Apple une fois par minute (définie comme 60 secondes) pendant 30 minutes :
ping -i 60 -c 30 apple.com(Le nom 'ping' vient du son que font les sonars.)
Essayer de pinger toutes les machines sur votre réseau local pour voir celles qui utilisent Rendezvous :
% ping 224.0.0.251Pingez l'adresse de broadcast de votre sous réseau local pour découvrir toutes les machines qui s'y trouvent :
% ping 10.0.1.255ou
% ping 192.168.1.255Regardez si votre routeur répond à :
% ping 0et qui répond à :
% ping 255.255.255.255Vous pouvez pinger une machine AppleTalk avec 'appleping'.
L'utilitaire traceroute montre le chemin vers des machines distantes en indiquant chaque 'hop' (saut) que fait un paquet sur son chemin à travers Internet.
La route est longue vers OSXFAQ.com...
% traceroute osxfaq.com traceroute to osxfaq.com (64.84.37.30), 30 hops max, 40 byte packets 1 valinor.zen (217.155.168.150) 21.229 ms 0.819 ms 0.353 ms 2 gauss-dsl1.wh.zen.net.uk (62.3.83.2) 19.78 ms 19.17 ms 20.999 ms 3 chrysippus-ve-131.wh.zen.net.uk (62.3.83.78) 22.385 ms 21.946 ms 22.521 ms 4 deleuze-ge-0-2-0.hq.zen.net.uk (62.3.80.81) 23.122 ms 22.709 ms 22.613 ms 5 suarez-so-0-0-0.te.zen.net.uk (62.3.80.62) 29.521 ms 29.589 ms 29.233 ms 6 lndnuk1icx1.wcg.net (195.66.224.105) 29.292 ms 29.049 ms 29.994 ms 7 nycmny2wcx2-oc12.wcg.net (64.200.87.149) 100.266 ms 100.063 ms 99.222 ms 8 nycmny2wcx3-oc48.wcg.net (64.200.87.78) 169.294 ms 169.843 ms 169.936 ms 9 chcgil1wcx3-oc48.wcg.net (64.200.240.37) 169.212 ms 170.859 ms 169.893 ms 10 dnvrco1wcx2-pos10-0.wcg.net (64.200.210.66) 169.951 ms 170.472 ms 170.171 ms 11 snfcca1wcx3-pos11-0.wcg.net (64.200.240.94) 170.758 ms 171.265 ms 171.403 ms 12 snfcca1wce1-pos3-0.wcg.net (64.200.199.238) 169.128 ms 170.197 ms 167.675 ms 13 snfcca1wce1-naciosystems-se.wcg.net (64.200.198.18) 168.242 ms 168.977 ms 169.301 ms 14 is10-0-0m.nov55c-75-003.nacio.com (64.84.1.9) 172.06 ms 171.154 ms 169.978 ms 15 if0-0-0m.nov55c-75-002.nacio.com (64.84.0.195) 172.116 ms 172.63 ms 171.409 ms 16 is11-1-1m.sfob-02.nacio.com (167.160.242.253) 173.154 ms 174.414 ms 173.645 ms 17 ife0-0m.sfoc-01.nacio.com (167.160.239.177) 173.634 ms 172.496 ms 173.64 ms 18 gw.scotthaneda.m-l.net (167.160.239.194) 178.804 ms 178.785 ms 177.821 ms 19 osxfaq.com (64.84.37.30) 179.822 ms 181.029 ms 182.053 ms
Si traceroute rate, essayer l'option '-p' avec un nombre de port élevé :
% traceroute -v -p 35353 osxfaq.com version graphique de traceroute
Essayez ce très bon site web pour une version plus graphique de traceroute :
http://visualroute.visualware.co.uk/
netstat fournit un certain nombre de statistiques vitales sur vos connexions réseau, vos tables de routage et d'autres informations du même type. Il est utile pour debugger votre connexion, ou juste pour fouiner un peu.
Quelques exemples :
Pour avoir une liste des connexions actuelles, incluant les noms des machines et les numéros de port locaux :
% netstat Active Internet connections Proto Recv-Q Send-Q Local Address Foreign Address (state) tcp4 0 286 saruman.zen.55040 osxfaq.com.http ESTABLISHED tcp4 0 284 saruman.zen.55039 osxfaq.com.http ESTABLISHED tcp4 0 0 saruman.zen.55038 osxfaq.com.http CLOSE_WAIT tcp4 0 0 localhost.1033 localhost.1006 ESTABLISHED tcp4 0 0 localhost.1006 localhost.1033 ESTABLISHED tcp4 0 0 localhost.1033 localhost.1019 ESTABLISHED tcp4 0 0 localhost.1019 localhost.1033 ESTABLISHED tcp4 0 0 localhost.1033 *.* LISTEN udp4 0 0 saruman.zen.ntp *.* udp4 0 0 localhost.ntp *.* udp4 0 0 localhost.49155 localhost.1002 udp4 0 0 localhost.49154 localhost.1002 udp4 0 0 localhost.1033 *.* Active LOCAL (UNIX) domain sockets Address Type Recv-Q Send-Q Inode Conn Refs Nextref Addr 25b2540 stream 4782 0 0 0 0 0 25b23b8 stream 0 0 0 25b24d0 0.. ...... ...... ......
Pour avoir une liste des tables de routage de votre machine :
% netstat -r Routing tables
Internet: Destination Gateway Flags Refs Use Netif Expire default valinor.zen UGSc 36 433 en0 localhost localhost UH 8 26887 lo0 169.254 link#4 UCS 0 0 en0 217.155.168.144/29 link#4 UCS 1 0 en0 saruman.zen localhost UHS 0 96 lo0 valinor.zen 0:50:7f:6:82:34 UHLW 36 201 en0 1072
Internet6: Destination Gateway Flags Netif Expire UH lo0 fe80::%lo0 Uc lo0 link#1 UHL lo0 fe80::%en0 link#4 UC en0 0:3:93:b2:d6:4 UHL lo0 fe80::%en1 link#5 UC en1 0:30:65:6:59:b2 UHL lo0 ff01:: U lo0 ff02::%lo0 UC lo0 ff02::%en0 link#4 UC en0 ff02::%en1 link#5 UC en1
(Utilisez l'option '-n' pour afficher les adresses IP au lieu des noms de machines.)
Vous devriez voir le routeur par défaut, votre nom de routage/adresse IP et son adresse MAC, en plus de plusieurs noms et adresses assignés à votre machine.
La commande :
arp -avous montre toutes les machines sur le sous réseau local pour lesquelles votre machine a un lien MAC à adresse IP. Quand vous êtes connectés à un routeur, vous ne verez probablement que les détails de votre routeur.
Demander des informations sur une machine avec 'host'
Pour obtenir l'adresse IP d'une machine, utilisez :
% host mayo-family.com.Cette commande retourne aussi le serveur mail pour ce domaine.
Il est conseillé de finir le nom de domaine avec un '.' (comme dans l'exemple ci-dessus) pour s'assurer qu'il ne soit pas interprété comme appartenant à votre propre domaine.
Pour faire l'inverse, c'est-à-dire obtenir un nom de machine à partir d'une adresse IP, donnez simplement l'adresse IP :
host 17.254.3.183(Voir aussi la Semaine 42 pour plus de conseils Internet.)
'host' a un certain nombre d'options. La plus utile est '-a' pour récupérer tous les enregistrements et afficher en mode explicite.
% host -a mayo-family.com Trying null domain rcode = 0 (Success), ancount=5 The following answer is not authoritative: The following answer is not verified as authentic by the server: mayo-family.com 79546 IN MX 10 mail.hostwizard.com mayo-family.com 79546 IN A 64.84.37.15 mayo-family.com 79546 IN NS ns1.hostwizard.com mayo-family.com 79546 IN NS dns2.intermag.com mayo-family.com 79546 IN NS dns3.intermag.com For authoritative answers, see: mayo-family.com 79546 IN NS dns2.intermag.com mayo-family.com 79546 IN NS dns3.intermag.com mayo-family.com 79546 IN NS ns1.hostwizard.com Additional information: mail.hostwizard.com 65327 IN A 64.84.37.6 ns1.hostwizard.com 80083 IN A 64.84.37.14 dns2.intermag.com 882 IN A 216.218.240.104 dns3.intermag.com 883 IN A 198.144.200.118
Notez que :
Les commandes 'dig' et 'nslookup' sont des alternatives à 'host' et peuvent être mieux adaptées à vos besoins.
% dig apple.com.
; <> DiG 8.3 <> apple.com. ;; res options: init recurs defnam dnsrch ;; got answer: ;; ->HEADER<- opcode: QUERY, status: NOERROR, id: 2 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 6, ADDITIONAL: 4 ;; QUERY SECTION: ;; apple.com, type = A, class = IN
;; ANSWER SECTION: apple.com. 26m56s IN A 17.254.3.183
;; AUTHORITY SECTION: apple.com. 1d23h43m9s IN NS nserver.asia.apple.com. apple.com. 1d23h43m9s IN NS nserver.euro.apple.com. apple.com. 1d23h43m9s IN NS nserver.apple.com. apple.com. 1d23h43m9s IN NS nserver2.apple.com. apple.com. 1d23h43m9s IN NS nserver3.apple.com. apple.com. 1d23h43m9s IN NS nserver4.apple.com.
;; ADDITIONAL SECTION: nserver.asia.apple.com. 1d8h48m29s IN A 203.120.14.5 nserver.euro.apple.com. 23h13m18s IN A 17.72.133.64 nserver3.apple.com. 4d22h14m31s IN A 17.112.144.50 nserver4.apple.com. 4d22h14m31s IN A 17.112.144.59
;; Total query time: 47 msec ;; FROM: saruman.mayo-family.com to SERVER: default -- 212.23.8.1 ;; WHEN: Sun May 4 20:47:50 2003 ;; MSG SIZE sent: 27 rcvd: 252
% nslookup apple.com. Server: ns0.zen.co.uk Address: 212.23.8.1
Non-authoritative answer: Name: apple.com Address: 17.254.3.183
Comme toujours, utilisez la commande 'man' pour en savoir plus.
La commande 'whois' fait une requête à whois.intemic.net pour découvrir le responsable, le propriétaire et les serveurs de nom pour un domaine.
% whois mayo-family.com
Whois Server Version 1.3
...
Domain Name: MAYO-FAMILY.COM Registrar: BULKREGISTER.COM, INC. Whois Server: whois.bulkregister.com Referral URL: http://www.bulkregister.com Name Server: DNS2.INTERMAG.COM Name Server: NS1.HOSTWIZARD.COM Name Server: DNS3.INTERMAG.COM Status: ACTIVE Updated Date: 27-feb-2003 Creation Date: 19-jul-2001 Expiration Date: 19-jul-2003 ...
Si le domaine n'a pas été enregistré par intemic, un deuxième whois est nécessaire. Dans ce cas une requête au serveur whois du responsable est nécessaire avec l'option '-h'.
% whois -h whois.bulkregister.com mayo-family.com Adrian Mayo 54 Greenland Mills Bradford-on-Avon, England BA15 1BL UK
Domain Name: MAYO-FAMILY.COM
Administrative Contact: Carlton Thomas domreg@gifford.co.uk Gifford Internet Services 14 Tyrrel Way, Stoke Gifford Bristol, England BS34 8UY UK Phone: +44 117 9397722 Fax: +44 117 9397733 Technical Contact: Carlton Thomas domreg@gifford.co.uk Gifford Internet Services 14 Tyrrel Way, Stoke Gifford Bristol, England BS34 8UY UK Phone: +44 117 9397722 Fax: +44 117 9397733
Record updated on 2001-07-19 11:28:07 Record created on 2001-07-19 Record expires on 2003-07-19 Database last updated on 2003-05-04 15:58:47 EST
Domain servers in listed order:
DNS2.INTERMAG.COM 216.218.240.104 DNS3.INTERMAG.COM 198.144.200.118 NS1.HOSTWIZARD.COM 64.84.37.14
'whois' pour les domaines non TLD
Pour faire une requête 'whois' pour un domaine qui n'est pas du plus haut niveau (Top Level Domain en anglais), par exemple '.co.uk', il faut utiliser un autre service 'whois'.
% whois -h whois.nic.uk bbc.co.uk
Domain Name: bbc.co.uk
Registrant: British Broadcasting Corporation
Registrant's Agent: The British Broadcasting Corporation t/a BBC Technology [Tag = BBC]
Relevant Dates: Last updated: 13-Mar-2001
Name servers listed in order: ns.bbc.co.uk 132.185.132.21 ns1.thny.bbc.co.uk 38.160.150.21 ns1.thdo.bbc.co.uk 212.58.224.21 ns1.bbc.co.uk 132.185.132.11
WHOIS database last updated at 21:20:01 04-May-2003
Et si quelqu'un connait une façon fiable de déterminer l'adresse whois pour les divers TLD et domaines nationaux, faites le nous savoir...
Pour exécuter une commande, ou des commandes, dans un nouveau shell, utilisez des parenthèses.
Pour exécuter plusieurs commandes sur une ligne, séparez les avec des point-virgules.
Par exemple, comparez les deux commandes suivantes qui font appel aux deux méthodes.
% (cd /; pwd); pwd / /Users/saruman
% cd / ; pwd ; pwd / /
Pour savoir pourquoi les sorties diffèrent, reportez vous à la partie 8 du manuel Unix dans le Learning Center (en anglais sur osxfaq.com).
Mac OS X Unix Tutorial 8 - Shell Scripting 1. New 19 May 2003
Ceci s'applique au shell 'tcsh'.
Pour rediriger une sortie standard, utilisez '>'. Ex :
ls -al * > listLes sorties et les messages d'erreur écrivent dans différents flux. Pour rediriger à la fois les sorties standards et les erreurs standards, utilisez '>&'. Ex :
ls -al kfhsdhdjhsjkhf >& listPour en savoir plus sur la redirection, reportez vous à la partie 7 du manuel Unix dans le Learning Centre (en anglais sur osxfaq.com).
Mac OS X Unix Tutorial 8 - Shell Scripting 1. New 19 May 2003
Le shell 'tcsh' ne permet pas de façon évidente de rediriger une sortie standard et une erreur vers des fichiers différents. Utilisez l'astuce suivante pour y arriver :
(ls -al filename > list ) >& list.errPour en savoir plus sur la redirection, reportez vous à la partie 7 du manuel Unix dans le Learning Centre (en anglais sur osxfaq.com).
Mac OS X Unix Tutorial 8 - Shell Scripting 1. New 19 May 2003
Le shell 'tcsh' ne permet pas de façon évidente de rediriger une erreur standard, mais pas la sortie standard. Utilisez l'astuce suivante pour y arriver :
(ls -al filename > /dev/tty) >& list.errMac OS X Unix Tutorial 8 - Shell Scripting 1. New 19 May 2003
Comment éviter les écrasements intempestifs de fichier
Si vous voulez éviter d'écraser accidentellement des fichiers avec des redirections, activez la variable 'noclobber' de 'tcsh'. Par exemple :
% set noclobber % ls .....list list.err ....
% ls > list list: File exists. % ls >! list %
Remarquez l'utilisation de '!' pour temporairement passer outre 'noclobber'.
Mac OS X Unix Tutorial 8 - Shell Scripting 1. New 19 May 2003
Pour tuer une application (ou un process) de la ligne de commande, nous devons d'abord trouver le numéro qui lui a été alloué : son Process ID ou PID. Par exemple :
% ps -axww | grep -i clock 15048 ?? S 0:00.65 /Applications/Clock.app/Contents/MacOS/Clock 15054 std R+ 0:00.00 grep -i clock
et ensuite utiliser la commande 'kill' :
% kill 15048Remarquez l'utilisation de l'option 'ww' qui assure que la sortie de 'ps' n'est pas tronquée, elle perdrait alors le nom pour lequel nous utilisons grep.
Un PID de -1 propage le signal à tous les process pour lesquels vous avez la permission nécessaire pour tuer.
Une autre façon de procéder est d'utiliser :
killall Clockqui tue par nom (sensible à la casse). Faites attention car cette commande tue tous les process qui correspondent au nom donné.
L'option '-m' de 'killall' prend une expression régulière en tant que nom de process, et tue tous les process qui lui correspondent.
Les commandes 'kill' et 'killall' envoient un signal 'TERM' au process, ce signal correspond à une demande au process de s'arrêter.
D'autres signaux sont disponibles, incluant
-KILL - fait au process une proposition qu'il ne peut refuser. Ceci tue toujours le process.
-HUP - dit au process de redémarrer. C'est utile pour redémarrer des démons (comme configd et lookupd), car ils vont relire leur fichier de configuration à la réception d'un signal -hup.
La commande :
% kill -lliste tous les signaux disponibles, et :
% man sigactiondonne plus de détail.
Voici un script pratique pour tuer des processus par leur nom :
% cat killerN'oubliez pas de rendre le script exécutable.
Plusieurs démons Unix laisse gentiment leur adresse. Voyez plutôt :
% ls /var/run/ AppleFileServer.pid cron.pid mDNSResponder.pid ntp.drift sshd.pid xinetd.pid StartupItems davlocks named.pid ntpd.pid sudo autodiskmount.pid httpd.pid ndc pppconfd syslog automount.pid inetd.pid netinfo_local.pid proxy syslog.pid configd.pid lookupd.pid niconfig_local.xml resolv.conf utmp
Elles devraient être indépendantes du nom du démon. Par exemple, les serveurs www devraient afficher leur pid dans 'httpd.pid'.
Vous pouvez créer un alias pratique pour redémarrer un démon :
% alias nfs-mount 'sudo kill -HUP `cat /var/run/automount.pid`'ce qui redémarrera le client et le serveur NFS après que de nouveaux partages et de nouvelles connexions aient été ajoutés.
Voici un script pratique pour redémarrer un démon :
% cat hanger #!/bin/sh if [ "$1" = "" ]; then echo "Liste des démons :" cd /var/run ls -1 *.pid | sed -e 's/.pid//' else echo "redémarrage du démon $1" sudo kill -HUP `cat /var/run/$1.pid` fi
Il listera les démons :
~ % hanger List of demons: AppleFileServer autodiskmount automount configd cron httpd inetd lookupd mDNSResponder named netinfo_local ntpd sshd syslog xinetd
et les tuera :
% hanger lookupdN'oubliez pas de rendre le script exécutable.
Pour démarrer et arrêter Apache à partir de la ligne de commande, utilisez l'utilitaire de contrôle d'Apache :
% sudo apachectl startPour faire en sorte qu'Apache démarre lorsque vous démarrez votre Mac, éditez le fichier :
/etc/hostconfigen étant sous root, et changez
WEBSERVER=-NO-en
WEBSERVER=-YES-
Si vous changez les fichiers de configuration d'Apache, vous devez redémarrer Apache pour qu'il les lise de nouveau. Pour faire ceci avec grace (sans perturber les connexions existantes d'un serveur en ligne), utilisez :
% sudo apachectl graceful Changer le répertoire root du WebServer
Par défaut, Apache sur Mac OS X utilise comme point de départ /Library/WebServer/Documents. Si vous voulez utiliser un autre répertoire, comme ~/Sites, éditez le fichier de configuration d'Apache :
% sudo pico /etc/httpd/httpd.confRemplacez cette ligne (ligne 363?) :
DocumentRoot "/Library/WebServer/Documents"par :
DocumentRoot "/Users/your-user-name-here/Sites"et cette ligne (ligne 388?) :
Directory "/Library/WebServer/Documents"par :
Directory "/Users/your-user-name-here/Sites"Vous pouvez accéder au manuel Apache en ligne avec l'URL : http://localhost/manual/
Apache écrit les informations d'accès dans :
/private/var/log/httpd/error_loget :
/private/var/log/httpd/access_logExaminez le registre d'erreur si vous avez des soucis en mettant en place le serveur. Examinez le registre d'accès pour voir qui regarde votre site.
Vous pouvez changer la quantité d'information de connexion qui est écrite dans ces fichiers. Par exemple, pour ajouter au fichier d'accès le site qui s'est connecté au vôtre et l'agent de l'utilisateur (le navigateur), procédez de la façon suivante.
Editez le fichier de configuration Apache
% sudo pico /etc/httpd/httpd.confCherchez :
CustomLog "/private/var/log/httpd/access_log" commonEt remplacez le par :
CustomLog "/private/var/log/httpd/access_log" combined Obtenir la liste des commandes intégrées au Shell
Le shell tcsh possède beaucoup de commandes intégrées pratiques (des commandes qui font partie du shell mais n'existent pas comme exécutables séparés dans /bin etc).
Pour faire la liste de toutes les commandes intégrées :
% builtins : @ alias alloc bg bindkey break breaksw builtins case cd chdir ...
Si la même commande existe à la fois comme exécutable séparé et comme commande intégrée du shell, c'est la commande intégrée qui sera exécutée. Pour utiliser l'exécutable, commencez la commande par "\".
% which which La table de hachage des commandes
Quand on donne au shell une commande à exécuter, il cherche d'abord dans ses commandes intégrées, et ensuite dans tous les répertoires spécifiés dans les variables PATH ou path environment/shell. Pour voir le chemin d'accès, utilisez une de ces deux commandes :
% echo $PATHDe façon à accélérer ce processus de recherche, le shell cherche dans ces répertoires quand il démarre et il stocke l'information en mémoire. Si vous ajoutez une nouvelle commande ou un script shell à un de ces répertoires, le shell ne les reconnaitra pas. Pour que le shell rafraîchisse son cache, utilisez la commande intégrée 'rehash'
% rehashS'il n'y a pas de réponse, c'est que tout va bien.
Essayez ceci :
% hashstat
La commande intégrée 'umask' indique au système de fichier les permissions par défaut qu'il doit appliquer aux fichiers et aux répertoires qui vont être créés. umask peut être placée dans votre fichier de démarrage tcsh, ou juste appliquée à une session de Terminal particulière.
Sans umask, les répertoires ont les permissions suivantes :
drwxrwxrwx 2 saruman staff 68 Jun 9 11:16 test-diret les fichiers ont les permissions suivantes :
-rw-rw-rw- 1 saruman staff 0 Jun 9 11:16 test-fileEn général, umask est réglée sur 022 :
% umask 022 % touch test-file % ls -al test-file -rw-r--r-- 1 saruman staff 0 Jun 9 11:22 test-file
Pour donner la permission d'écriture à votre groupe :
% rm test-file % umask 002 % touch test-file % ls -al test-file -rw-rw-r-- 1 saruman staff 0 Jun 9 11:23 test-file
Pour les fichiers partagés :
% rm test-file % umask 000 % touch test-file % ls -al test-file -rw-rw-rw- 1 saruman staff 0 Jun 9 11:23 test-file
Pour les fichiers privés :
% rm test-file % umask 077 % touch test-file % ls -al test-file -rw------- 1 saruman staff 0 Jun 9 11:23 test-file
La commande intégrée 'nice' est utilisée pour exécuter une commande avec une priorité plus élevée ou moins élevée que la priorité par défaut. Une valeur négative de nice assure que la commande bénéficie d'une plus grande part du CPU (haute priorité), et une valeur positive assure que la commande en obtient une part plus petite (basse priorité).
Normalement, une commande est créée avec une valeur de nice de 4 :
% ./test.sh
% ps -axlhww | grep test.sh UID PID PPID CPU PRI NI ... 501 9997 3457 0 27 4 ...
indiquant une priorité (PRI) de 31-4=27 et in nice (NI) de 4.
Pour créer une commande de basse priorité, utilisez :
% nice +20 ./test.sh % ps -axlhww | grep test.sh UID PID PPID CPU PRI NI ... 501 10036 3457 0 11 20 ...
indiquant une priorité de 31-20=11 (basse) et un nice de 20 comme on l'a demandé.
Pour augmenter la priorité, il faut être super-utilisateur :
% sudo -s
# nice -10 ./test.sh
% ps -axlhww | grep test.sh
UID PID PPID CPU PRI NI ...
0 10142 10130 0 41 -10 ...
Vous pouvez aussi regarder la commande 'renice' (non intégrée), qui ajuste la priorité des processus en cours :
% man renice
La commande intégrée 'exec' permet à un utilisateur d'exécuter une commande à la place du shell. Le shell lance la commande et se retire.
Cela peut être utile pour lancer une commande qui s'exécute comme un démon et ne nécessite pas son shell d'origine.
% exec my-daemon
Quand le shell 'tcsh' démarre, il lit et exécute plusieurs fichiers de script. Vous êtes libres de les changer (ou d'en créer) si vous voulez personnaliser votre environnement en ligne de commande. Ces fichiers sont :
/etc/csh.cshrcVous pouvez ajouter des commandes Unix ou des commandes du shell 'tcsh' à ces fichiers. Les deux premiers fichiers concernent tous les utilisateurs, et les deux suivants sont propres à chaque utilisateur.
Pour une compatibilité en amont avec le shell 'csh' (à partir duquel est dérivé le shell 'tcsh'), le fichier de script :
~/.cshrcpeut ou ne peut pas être exécuté quand le shell 'tcsh' démarre.
En l'absence de '~/.tcshrc', '~/.cshrc' est exécuté. A partir du moment où vous créez '~/.tcshrc', '~/.cshrc' n'est plus exécuté. Ainsi, ne vous contentez jamais d'avoir ces deux fichiers exécutés. Choisissez en un, de préférence '~/.tcshrc', et utilisez le même si on vous conseille de rajouter des lignes à l'autre. Les deux sont interchangeables.
Shells de Connexion et d'Interaction
A quoi correspondent les Shell de Connexion et d'Interaction ?
L'ouverture d'une fenêtre Terminal lance un shell interactif avec connexion.
L'exécution d'un script shell lance un shell non interactif sans connexion.
Taper 'tcsh' à la ligne de commande lance un shell interactif sans connexion.
Les shells avec connexion diffèrent de part le fait qu'ils lisent et exécutent :
/etc/csh.loginalors que les shells sans connexion ne le font pas.
Les shells interactifs sont attachés à une fenêtre de Terminal de façon à ce que vous puissiez y taper des commandes. Les shells non interactifs obtiennent leurs commandes à partir d'un script.
Quelques terminaux (tels que xterm qui tourne sous X11) ne lance pas par défaut de shell de connexion. Pour faire en sorte que xterm le fasse, et donc se comporter comme le Terminal dApple, ajoutez ceci à ~/.Xdefaults :
# xterm Commandes de Connexion exclusivement
Suite de l'astuce de Mercredi ...
Optimisez la séquence de démarrage du shell en utilisant les fichiers de démarrage du shell exclusivement de connexion :
/etc/csh.loginDans ces fichiers, configurez l'aspect de l'environnement qui persiste, tel que les variables d'environnement. Cela s'applique surtout aux commandes du genre :
setenv PATH ${PATH}:xxxqui en rajoute à une variable d'environnement. Une commande comme celle-ci ne doit pas être exécutée plus d'une fois sinon votre PATH va grandir et grandir encore.
Commandes exclusivement Interactives
Suite de l'astuce de Mercredi ...
Optimisez le séquence de démarrage du shell. Beaucoup de commandes dans in ~/.tcshrc ne sont pas nécessaires pour les shells non interactifs. La plupart, en fait, comme celles qui configurent les variables shell et les alias, et la commande bindkey. Sortez ces commandes pour les shells non interactifs.
Incorporez cette instruction près du début de ~/.tcshrc
Puis entourez toutes les commandes exclusivement interactives avec :
if ($?interactive) then
... lieu des commandes interactives...
endif
Des astuces précédentes (des semaines 1, 13 et 31—pas encore traduites sur Project:Omega) ont abordé le 'find'. Les astuces de cette semaine vont plus loin d'utilisation cette commande puissante en combinaison avec la commande 'xargs'.
La Semaine 13 (en anglais) donnait un exemple d'utilisation de l'option '-exec' du 'find' pour exécuter une commande sur tous les fichiers trouvés :
% find . -iname "*.ws" -exec grep -il warning {} ;Le même effet peut être obtenu en montant un 'pipe' avec 'xargs' :
% find . -iname "*.ws" | xargs grep -il warning'xargs' est une commande Unix de plein droit et n'est pas spécifique à 'find'. Elle constitue une commande à partir des paramètres qui proviendront de la sortie de la commande 'find'.
grep -il warning file1 file2 file3 file4 .......
Cette astuce se réfère à celle de lundi...
% find . -iname "*.ws" -exec grep -il warning {} ;contre :
% find . -iname "*.ws" | xargs grep -il warning...certains pourront vous dire que monter un 'pipe' avec 'xargs' est moins efficace que d'utiliser l'option intégrée '-exec'. Ce n'est pas le cas, et en fait, le deuxième exemple ira au moins dix fois plus vite que le premier...
Pourquoi?
Parce que '-exec' exécutera la commande 'grep' une fois pour chaque fichier trouvé. Dans cet exemple, plus de 200 fichiers correspondaient à "*.ws". 'xargs' d'un autre côté, absorbe tous les arguments et les passe à 'grep' en une fois.
L'exemple de lundi...
% find . -iname "*.ws" | xargs grep -il warning...marche car 'grep' peut prendre une longue liste de fichiers à traiter. Si une commande ne prend qu'un fichier à la fois, utilisez l'option '-n1'.
% find . -iname "*.ws" | xargs -n1 my-simple-scriptL'option '-t' est utile (trace) - elle fait en sorte que 'xargs' mette en sortie standard la commande qu'il a formée et qu'il va exécuter.
% find . -iname "*.ws" | xargs grep -t -il warning
Si 'find' trouve beaucoup, beaucoup de fichiers, la ligne de commande résultante formée par 'xargs' peut être trop longue. Limitez-la en utilisant l'option '-n' qui indique le nombre maximum de paramètres que 'xargs' passera à la commande (à 'grep' dans cet exemple).
% find . -iname "*.ws" | xargs -n100 grep -il warning...fait en sorte que 'xargs' appelle 'grep' une fois qu'il a 100 noms de fichier. Si 350 noms de fichier étaient trouvés, 'xargs' appellerait 'grep' quatre fois.
Prenez vim. Mac OS X embarque 'vi'. Vim est une version améliorée de 'vi', et il est disponible en trois versions : Terminal pur, X11 et GUI Carbon.
La page d'accueil principale de vim est : http://www.vim.org
La page de téléchargement de la version Mac est : http://www.vim.org/download.php#mac
Pour la version Interface Graphique Carbon : http://macvim.swdev.org/OSX
Marc Liyanage maintient les versions ligne de commande des déclinaisons Terminal pur et X11 : http://www.entropy.ch/software/macosx/welcome.html#vim
Les astuces de cette semaine ne sont pas un tutoriel sur vim pour les débutants mais elles seront pratiques pour ceux qui ont dépassé le stade de la touche 'esc' et de la touche 'i'.
Apprenez les touches de mouvement du curseur. Les plus utiles sont :
{ retour au début du paragraphe(plus les touches curseur évidentes).
Utiliser couper, copier et coller :
d coupe (delete)y et d doivent être suivies par un mouvement de curseur (voir l'astuce de Mardi) et elles copieront ou effaceront à partir du curseur jusqu'à l'emplacement de déplacement cible.
Exemples :
d$ efface jusqu'à la fin de la ligneRaccourcis :
dd est le raccourci pour effacer la ligne courante
Vim comporte 26 buffers (de a à z) en plus du buffer général sans nom. Précédez une commande d'un nom de buffer et la commande chagera ce buffer ou en retirera ses informations.
Suite de l'exemple de Mercredi :
"ay) copie jusqu'à la fin de la phrase et place le texte dans le buffer nommé "aNotez que le buffer sans nom est toujours mis à contribution en plus de n'importe quel buffer nommé.
Vous pouvez ajouter du texte à un buffer en le nommant avec une lettre majuscule.
"Ad$ coupera le texte jusqu'à la fin de la ligne et ajoutera le texte coupé à celui déjà présent dans le buffer "a
Vim est doté de 26 signets intitulés de a à z. Placez un signet avec ma (jusqu'à mz) et rappelez le (replacez le cursuer à cet endroit) avec 'a (jusqu'à 'z).
Copiez ou collez une portion de texte avec :
Cela copiera en plus la section dans le buffer intitulé "b.
En plus :
'' (deux guillemets) alterne entre la position courante et la position précédente du curseurConstituez des signets sur plusieurs fichiers avec les 36 signets inter-fichier mA (jusqu'à mZ, et m0 à m9). Rappelez les comme d'habitude avec 'A ou `A (jusqu'à 'Z, '9).
...pour Additionner des Tailles de Fichiers
Les astuces de cette semaine sont tirées des réponses envoyées aux nombreux mails que j'ai reçus me demdant : "Comment faire ceci et cela ?"
Comment puis je faire pour avoir le total de tous les fichiers Photoshop (*.psd) situés dans mon répertoire Départ ?
% find ~ -iname "*.psd" -print0 | xargs -0 du -chVoilà ! - 316M.
La commande standard Mac OS X 'du' ne comprend pas l'option '-h' (affichage lisible par un humain). Utilisez -k à la place pour voir les tailles de fichiers en K-octets.
Le package GNU 'fileutils' contient des versions plus récentes de beaucoup de commandes de base, dont 'du' et une version colorisée de 'ls'. Il s'obtient plus facilement en utilisant Fink.
...des Recherches dans d'Importants Répertoires
Comment faire pour afficher les Répertoires dont le contenu dépasse les 100 Mo ?
Des astuces précédentes ont couvert une question similaire applicable à tous les fichiers qui dépassent une taille donnée. Par exemple, trouver tous les fichiers dont la taille dépasse 20 Mo :
% find . -size +40000Pour appliquer ceci à des répertoires, utilisez :
% du -k ~ | egrep "^[0-9]{6,}"Cela affichera le nom des répertoires dont la taille en K-octets est sur six chiffres ou plus (contrôlé par {6,}).
...pour Effacer des Lignes Blanches
Comment faire pour supprimer des lignes vides dans un fichier ?
En utilisant 'sed' :
% sed '/^$/d' in-file > out-fileEn utilisant 'tr' :
% tr -s \n < in-file > out-fileSi le fichier comporte des lignes contenant des espaces :
% sed '/^[ ]*$/d' in-file > out-fileSi les lignes contiennent aussi des tabulations :
% sed '/^[ t]*$/d' in-file > out-fileMAIS, la commande 'sed' d'OS X semble ne pas comprendre que 't' veut dire tabulation.
...Traiter une Commande comme une Fonction
Ceci est en rapport avec une question fréquente, mieux illustrée par un exemple.
La commande 'tr' traduit ou retire les caractères du contenu d'un fichier. Comme la plupart des commandes, elle lit et écrit des fichiers ou la sortie standard. Par exemple, pour retirer des espaces utilisez :
% tr -d " " < in-file > out-fileComment pouvons nous utiliser une commande comme 'tr' dans un script shell pour retirer les espaces dans le contenu d'une variable ? L'effet souhaité est tel que si nous disions :
var = tr ($var);Le secret tient dans le fait de diffuser le contenu du paramètre d'entrée et de capturer le flux de sortie, ainsi :
Dans tcsh utilisez :
set var=`echo $var | tr -d " "`Dans sh utilisez :
var=$( echo $var | tr -d " " ) ...Retirer les espaces du nom d'un fichier ?
Comment puis-je éliminer les espaces de tous mes noms de fichier ?
Ce script 'sh' fera en sorte de ne pas avoir deux noms de fichier qui diffèrent dans un répertoire que par des espaces et de n'avoir aucun nom de répertoire avec des espaces.
% cat sh2 #!/bin/sh target_fn=$( echo $1 | tr -d " " ) if [ ! "$1" = "$target_fn" ]; then echo mv "$1" "$target_fn" mv "$1" "$target_fn" fi
% ls -R1 .: dirname file name file2 name sh sh2 tsh
dirname: file2 name file3name
% find . -print0 | xargs -0 -n1 ./sh2 mv ./dirname/file2 name ./dirname/file2name mv ./file name ./filename mv ./file2 name ./file2name
% ls -R1 .: dirname file2name filename sh sh2 tsh
dirname: file2name file3name
...Utiliser Grep sur plusieurs chaînes (OU)
Comment utiliser grep pour rechercher les fichiers contenant les chaînes string1 OU string2?
% grep -e "apple" -e "microsoft" *.txt'-e' introduit à une expression régulière de 'grep', qui recherche l'occurence de chacune des expressions régulières listées, dans chaque fichier.
En utilisant le 'grep' étendu ('egrep' ou 'grep -E') on peut spécifier :
% egrep "(microsoft|apple)" *.txtLe 'grep' étendu comprend les expressions régulières étendues. Le 'grep' dtandard ne comprend que les expression régulières classiques.
...Utiliser Grep sur plusieurs chaînes (ET)
Comment puis-je utiliser 'grep' pour rechercher les chaînes string1 ET string2 dans plusieurs fichiers ?
% grep -l "apple" *.txt | xargs grep -H "microsoft"'-l' (lettre elle) dans le premier 'grep' fait en sorte qu'il liste que les noms de fichiers, qui sont alors passés au second 'grep'. '-H' indique au second 'grep' d'imprimer le nom de fichier pour chaque correspondance.
Perl et 'awk' feront cela aussi, et j'ai l'intention de les aborder dans un tutoriel du Learning Centre.
Y a t'il une manière plus élégante de faire cela avec 'grep' ?
...Trouver des fichiers d'un type donné
Comment puis-je localiser tous les scripts shell Bourne ou tous les fichiers texte dans mon répertoire Départ ?
Nous savons tous comment utiliser 'find' pour faire cela en se basant sur l'extension de fichier. Mais comment faire avec le contenu des fichiers, ce qui était requis par cette question ?
Utilisez la commande 'file' combinée avec 'find' et 'grep' :
% find . -print0 | xargs -0 file | egrep "(Bourne|Tenex)" ./sh: Texte de script shell Bourne ./sh2: Texte de script shell Bourne ./tsh: Texte de script shell Tenex C
trouvera tous les scripts 'sh' et 'tcsh'. La magie est spécifiée par /etc/magic.
Le Vendredi de la Semaine 45 nous donnait un script pour faire exactement cela. Il ne marche cependant pas toujours parce que quelques petits démons malicieux ajoutent des données à leur fichier .pid :
% sudo cat /var/run/sendmail.pidChangez le script pour utiliser 'head' au lieu de 'cat', de façon à couper les lignes supplémentaires :
...
Voir Semaine 50 pour les astuces précédentes sur vim.
Utilisez la commande 'new' pour séparer l'écran de façon à éditer plusieurs fichiers dans la même fenêtre Terminal.
:newsépare l'écran en deux moitiés et crée un nouveau buffer d'édition, et :
:new file-1sépare et lit 'file-1' dans le nouveau buffer d'édition.
Utilisez ctrl-WW (ou ctrl-W ctrl-W) pour basculer d'un buffer/fichier à l'autre.
Vim peut aussi diviser la fenêtre verticalement, ce qui est utile pour comparer deux fichiers côte à côte.
:vert new [file-1]séparera l'écran verticalement et lira optionnellement le fichier file-1 dans le second buffer.
La commande :
% vimdiff file-1 file-2va lancer vim avec deux fichiers, créer une séparation verticale et marquer toutes les différences entre les deux fichiers.
Autrement, si vous déjà êtes en train d'éditer file-1, utilisez :
:diffsplit file-2ou
:vert diffsplit file-2pour charger file-2 et voir les différences.
Edition par lot de plusieurs fichiers
La commande :
% vim f1 f2 f3 f4 f5va faire en sorte que vim lise les cinq fichiers nommés et comence à éditer f1.
Pour se déplacer entre les fichiers, utilisez :
:n - prochain fichier de la liste:wn ou :wprev est nécessaire pour écrire les changements puis éditer le prochain fichier, si le fichier en cours a été changé.
Listez les buffers avec :
:bufferset passez à un buffer spécifique (buffer 2, par exemple) avec :
:b2
Pour ceux qui sont des habitués des raccourcis de vim, en voici quelques-uns qui peuvent être rajoutés à votre fichier .vimrc.
Merci à Mike Schienle
" Erreurs de typographie ab teh the ab pritn print
" Touches " Elles reposent sur des blocs marqués par a (début) et par b (fin)
" D supprime tout entre les marques a et b map D :'a,'bd
" Effacement P - place le buffer a à la position actuel du curseur map P :pu a
" Effacement Y - rassemble a-b dans le buffer a map Y :'a,'by a
" Etoile c - convertit en minuscule map *c :'a,'bs/<[A-Z]/l&/g
" Etoile C - convertit en majuscule map *C :'a,'bs/<[a-z]/u&/g
Variables de Réglage et d'Environment
Les astuces de cette semaine comparent des tâches ordinaires effectuées sous tcsh par rapport à sh/bash. Ce sera une référence pratique si, comme moi, vous passez sans arrêt de l'un à l'autre et mélangez souvent les syntaxes.
Comment régler les variables et les variables d'environnement :
tcsh sh/bash set var = value % var=value setenv ENV value % ENV=value; export ENV
Sous bash (en plus de sh) les variables peuvent être déclarées et marquées comme étant exportées et/ou en lecture seule :
declare [-options] var=value
Pour tcsh :
stdout cmd >fn stderr (>/dev/tty) >&fn2 both cmd >& fn both diff files (cmd >fn) >&fn2 stdin cmd
to append >> no clobber >!
pipe stdout cmd | cmd2 pipe both cmd |& cmd2
Pour sh/bash :
stdout cmd >fn stderr cmd 2>fn both same file cmd >fn 2>&1 (cmd &>fn - bash) both diff files cmd >fn 2>fn2 stdin
to append >>fn no clobber >|fn
pipe stdout cmd | cmd2 pipe both cmd 2>&1 | cmd2
close stdout cmd >&- close stderr cmd 2>&- close stdin cmd <&- open file cmd <>fn
Les fichiers suivants sont exécutées lorsque le shell démarre en mode interactif et dans l'ordre donné. Les démarrages du shell de connexion ainsi que de non-connexion sont indiqués.
Shell de connexion tcsh :
% tcsh -lShell de connexion bash :
% bash --loginShell de non-connexion tcsh :
% tcshShell de connexion bash :
% bash Constructions de Contrôle 1 (Choix)
Le langage de script de tcsh ressemble beaucoup au langage de programmation 'c' (d'où le 'c' de tcsh) alors que ce n'est pas le cas de sh/bash.
Construction 'if' :
#!/bin/tcsh
if ("$1" == "positive") then
echo "Oui"
else if ("$1" == "negative") then
echo "Non"
else
echo "Peut-être"
endif
#!/bin/sh
if [ "$1" = "positive" ]; then
echo "Oui"
elif [ "$1" = "negative" ]; then
echo "Non"
else
echo "Peut-être"
fi
Construction 'switch/case' :
#!/bin/tcsh
switch ("$1")
case "positive":
echo "Oui"
breaksw
case "negative":
echo "Non"
breaksw
default:
echo "Peut-être"
breaksw
endsw
#!/bin/sh
case "$1" in
"positive")
echo "Oui"
;;
"negative")
echo "Non"
;;
*)
echo "Peut-être"
;;
esac
Constructions de Contrôle 2 (Boucle)
Le langage de script de tcsh ressemble beaucoup au langage de programmation 'c' (d'où le 'c' de tcsh) alors que ce n'est pas le cas de sh/bash.
Boucles 'for' :
#!/bin/tcsh
foreach word (hello goodbye au-revoir)
echo $word
end
#!/bin/sh
for word in hello goodbye au-revoir
do
echo $word
done
Boucles 'while' :
#!/bin/sh n=0 while [ ! $n = 10 ] do echo $n n=$(expr $n + 1) done
#!/bin/tcsh set n = 0 while ($n != 10) echo $n set n = `expr $n + 1` end
Fichiers curieusement intitulés
Si vous avez un nom de fichier qui ressemble à :
% ls Z* Z???Il se peut qu'il contienne des caractères non-standard. Utilisez le complément par tabulation pour révéler le nom de fichier :
% ls Z(Remarquez que les noms de fichier n'apparaissent pas aussi bizarre quand ils sont affichés dans votre navigateur)
Le fichier peut être renommé ainsi :
% mv ZSi la partie visible du nom de fichier n'est pas unique :
% ls dalors l'astuce de Mardi pourra être appliquée....
Fichiers curieusement intitulés II
Suite de l'astuce de Lundi, si la partie visible du nom de fichier n'est pas unique :
% ls dutilisez le n° inode pour identifier le fichier.
% ls -i 590795 Danger 579654 bvt 563546 page2.htm 578980 tvb 590442 D??????????? 560810 Cantata.txt 563547 page3.HTML 529632 users 590441 D??#^ ...
puis utilisez 'find' pour le renommer :
% find . -inum 590442 -exec mv {} D-file ;
Quelques fois, la réparation d'un disque peut aider à rendre les fichiers fantômes bizarres un peu plus solides.
Pour faire cela, démarrer votre machine en mode mono-utilisateur en maintenant pressées les touches Commande et S
Pour réparer le volume de démarrage, tapez :
# fsck -yPour réparer d'autres partitions, tapez :
# fsck_hfs -y /dev/disk0sXoù X représente le numéro de tranche (partition) identifié par :
% pdisk Répertoires profondément imbriqués
Des commandes (telle que fsck) peuvent quelques fois échouer à cause de répertoires trop imrbiqués les uns dans les autres. De telles imbrications peuvent être créées par des scripts bogués.
Recherche ceci sur le système de fichier avec :
% sudo find / -mindepth 30(pour trouver des imbrications à plus de 30 niveaux).
Si vous êtes incapable d'effacer un fichier ou de vider la corbeille, allez voir cet article dans le Learning Centre -> Comment vider une corbeille récalcitrante (en anglais).
L'astuce de cette semaine améliore le tutoriel du Learning Centre sur le scripting, partie 8 et partie 9.
Notez que ces astuces sont pour des scripts 'sh' ou 'bash'.
Le paramètre spécial shell $0 contient le nom du script mais sous sa forme étendue avec le chemin d'accès. Pour n'afficher que le nom du script utilisez ${0##*/}
$ cat usageMac OS X Unix Tutorial 9 - Shell Scripting 2. New 8 Septembre.
Les conditions dans les instructions 'if', 'elif' et 'while' peuvent contenir des éléments AND, OR et NOT. Par exemple, pour tester si le paramètre 1 est "-p" AND que ke paramètre 2 est vide, utilisez :
if [ "$1" = "-p" -a "$2" = "" ]; thenLe '-a' représente AND.
Utilisez '-o' pour OR.
Pour inverser une condition utilisez le point d'exclamation (!). Par exemple pour tester qu'un fichier n'est pas un répertoire :
if [ ! -d "$file" ]; thenMac OS X Unix Tutorial 9 - Shell Scripting 2. New 8 Septembre.
Pour tester qu'un volume est monté, par exemple /Volumes/your-user, il est nécessaire de vérifier que /Volumes/your-user existe AND qu'il est n'est pas un fichier ou un répertoire classique. Une façon de faire cela consiste à examiner la sortie de df :
mounted=$(df | grep "/Volumes/$USER")Si le volume n'est pas monté alors la 'mounted' sera une chaîne vide. Notez que la variable d'environnement $USER correspond au nom court de l'utilisateur actuel.
On peut utiliser la condition :
if [ ! "$mounted" ]; then instruction pour monter /Volumes/$USER fi
parce qu'une chaîne vide renvoi la valeur FALSE.
Mac OS X Unix Tutorial 9 - Shell Scripting 2. New 8 Septembre.
Un volume AppleShare peut être monté avec les lignes suivantes :
mkdir /Volumes/$USERCela monte le répertoire Départ de l'utilisateur actuel localisé sur le serveur 'SERVER' à l'endroit /Volumes/nom-court-utilisateur.
Par exemple, le script :
$ cat mount-user #!/bin/sh
mounted=$(df | grep "/Volumes/$USER")
if [ ! "$mounted" ]; then echo "Mounting /Volumes/$USER" mkdir /Volumes/$USER mount_afp afp://$USER@your-server-address-here/$USER /Volumes/$USER > /dev/null else echo "/Volumes/$USER already mounted" fi
Montera mon répertoire Départ (saruman) localisé sur le serveur sous /Volumes/saruman :
$ ls /VolumesMac OS X Unix Tutorial 9 - Shell Scripting 2. New 8 Septembre.
Un Script de Montage Utilisateur
Voici un script qui utilise les astuces données cette semaine et les tutoriels de programmation shell du Learning Centre partie 8 et partie 9.
Il monte le répertoire départ de l'utilisateur en cours sur le serveur $SERVER, sur la machine locale au point de montage $AFP_MOUNT/$USER.
Il utilise deux variables d'environnement qui doivent être renseignées avant que le script ne démarre :
AFP_MOUNT pour indiquer où monter les volumes (en général '/Volumes')
SERVER pour l'adresse réseau du serveur
Un mot de passe peut être donné en option avec '-p password'. Sinon, mount_afp vous demandera votre mot de passe dans une pop-up ou le prendra dans le trousseau.
$ cat mount-user #!/bin/sh
# monte le répertoire départ de l'utilisateur en cours # sur le serveur dans le répertoire afp de montage #
if [ ! "$1" = "" -a ! "$1" = "-p" ]; then echo "Utilisation : ${0##*/} [-p password]" echo " monte le répertoire départ de ${USER} echo " sur le serveur à $AFP_MOUNT/$USER" exit fi
if [ "$1" = "-p" -a "$2" = "" ]; then echo "Utilisation : ${0##*/} [-p password]" echo " donne un mot de passe" exit fi
# si le mot de passe est donné, ajoute ":" au début # pour être en conformité avec la syntaxe de montage if [ "$1" = "" ]; then pass="" else pass=":"$2 fi
# vérifie s'il est déjà monté # mounted=$(df | grep "$AFP_MOUNT/$USER")
# s'il n'est pas monté, s'assure que le point # de montage (répertoire) est disponible # if [ ! "$mounted" ]; then if [ ! -d $AFP_MOUNT/$USER ]; then if [ -e $AFP_MOUNT/$USER ]; then rm -f $AFP_MOUNT/$USER fi mkdir $AFP_MOUNT/$USER fi mount_afp afp://$USER$pass@$SERVER/$USER $ALM_AFP_MOUNT/$USER > /dev/null disktool -r fi
# retourne 0 si aucun montage n'a été effectué, 1 sinon # if [ ! "$mounted" ]; then exit 1 else exit 0 fi
Mac OS X Unix Tutorial 9 - Shell Scripting 2. New 8 Septembre.
Un lien est un fichier qui 'pointe' vers un autre fichier. Il y en a deux variétés : les liens symboliques et les liens dures (voir Mardi).
Un lien symbolique est créé en utilisant la commande 'ln' en spécifiant l'option '-s' pour symbolique.
% echo "Je suis le fichier original" > orig-file % /bin/ls -l *-file lrwxr-xr-x 1 saruman staff 9 ... link-file -> orig-file -rw-r--r-- 2 saruman staff 23 ... orig-file
Le lien symbolique est illustré par le premier caractère 'l' dans un long listing et comme pointant vers le fichier d'origine.
% cat orig-file'link-file' est tout simplement un fichier qui contient du texte décrivant le chemin d'accès absolu vers 'orig-file', et qui contient un indicateur paramétré pour dire "je suis un lien symbolique". Les deux fichiers peuvent être n'importe où sur le système de fichiers - répertoires différents, partitions, disques ou machines différentes.
Quand un 'link-file' est accédé, le lien est automatiquement suivi et résulte en l'accès de 'orig-file'.
Si 'orig-file' est déplacé ou renommé le lien est brisé.
Un lien dur est créé par la commande 'ln' mais SANS spécifier l'option '-s'.
% ln orig-file hard-file % /bin/ls -l *-file -rw-r--r-- 2 saruman staff 23 ... hard-file lrwxr-xr-x 1 saruman staff 9 ... link-file -> orig-file -rw-r--r-- 2 saruman staff 23 ... orig-file
% cat orig-file Je suis le fichier d'origine % cat hard-file Je suis le fichier d'origine
'hard-file' n'est pas un nouveau fichier mais une nouvelle entrée de répertoire qui pointe vers les données du fichier original (le même endroit sur le disque). En termes techniques, les deux entrées de répertoire font référence au même inode.
Les deux fichiers sont en fait les mêmes et il n'est pas possible de déterminer qui est l'original et qui est le lien dur.
Les deux fichiers peuvent être renommés ou déplacés sans briser le lien.
Les liens durs ne peuvent être créés pour des partitions ou des disques différents. Cela vient du fait que les inodes appartiennent à une partition particulière et ne sont pas uniques dans un ensemble de partitions ou de disques.
Un alias est géré par le Finder et n'est pas reconnu par Unix. Un Alias comporte un data fork vide avec les informations relatives à l'alias qui sont stockées dans le resource fork.
(Crée un alias vers orig-file en utilisant le Finder.) % /bin/ls -l *-file -rw-r--r-- 1 saruman staff 0 ... alias-file -rw-r--r-- 2 saruman staff 23 ... hard-file lrwxr-xr-x 1 saruman staff 9 ... link-file > orig-file -rw-r--r-- 2 saruman staff 23 ... orig-file
% cat orig-file Je suis le fichier d'origine % cat alias-file %
Unix ne voit que les data fork et considère les 'alias-file' comme étant vides. Le Finder reconnaît les liens symboliques et les liens durs. La copie d'un alias avec la commande Unix 'cp' ne créera qu'un fichier vide.
Remarquez que 'ls' avec l'option -s reconnaît le resource fork lors du calcul de blocs occupés par le fichier (blocs de 36k ou de moitiés de 72K).
% /bin/ls -sl *-file 72 -rw-r--r-- 1 saruman staff 0 ... alias-file 8 -rw-r--r-- 2 saruman staff 23 ... hard-file 8 lrwxr-xr-x 1 saruman staff 9 ... link-file > orig-file 8 -rw-r--r-- 2 saruman staff 23 ... orig-file
Beaucop de commandes acceptent des options qui affectent la manière dont elles traitent les liens — en général pour contrôler qu'elles doivent traiter le lien lui-même ou suivre le lien et traiter le fichier cible. Cela s'applique seulement aux liens symboliques.
On peut dire à 'ls' de suivre le lien avec l'option '-L':
% ln -s ~/Documents/Letters/Channel Dynamics a-letter % /bin/ls -l a-letter lrwxr-xr-x 1 saruman staff 49 ... a-letter > /Users/saruman/Documents/Letters/Channel Dynamics % /bin/ls -lL a-letter -rw-r--r-- 1 saruman staff 20480 ... a-letter
et elle peut montrer les numéros d'inode avec l'option '-i':
% ls -l i *-file 678102 -rw-r--r-- 1 saruman staff 0 ... alias-file 678094 -rw-r--r-- 2 saruman staff 23 ... hard-file 678095 lrwxr-xr-x 1 saruman staff 9 ... link-file > orig-file 678094 -rw-r--r-- 2 saruman staff 23 ... orig-file
Remarquez que le lien dur et le fichier d'origine ont le même numéro d'i-node.
D'autres commandes acceptent les options '-H', '-L', et '-R' qui signifient en général :
-H Si l'option -R est spécifiée, les liens symboliques sont suivis sur la ligne de commande. (Liens symboliques rencontrés dans l'arbre transversal ne sont pas suivis.)
-L Si l'option -R est spécifiée, tous les liens symboliques sont suivis.
-P Si l'option -R est spécifiée, aucun lien symbolique n'est suivi.
Ces commandes sont les suivantes :
'test' (aussi connu sous '[') peut tester un lien symbolique avec '-L':
-L file - Vrai si le fichier existe et est un lien symbolique.
La commande 'lndir' crée un répertoire ombre de liens symboliques vers un autre répertoire.
Par exemple, construisez la structure suivante :
% mkdir ln-testFaites un répertoire ombre :
% cd ../Examinez le répertoire ombre créé par 'lndir' :
% /bin/ls -lR total 16 lrwxr-xr-x 1 saruman staff 12 Oct 5 11:44 a -> ../ln-test/a lrwxr-xr-x 1 saruman staff 12 Oct 5 11:44 b -> ../ln-test/b drwxr-xr-x 4 saruman staff 136 Oct 5 11:44 c
./c: total 16 lrwxr-xr-x 1 saruman staff 17 Oct 5 11:44 a -> ../../ln-test/c/a lrwxr-xr-x 1 saruman staff 17 Oct 5 11:44 b -> ../../ln-test/c/b
Si vous souhaitez éditer un groupe de fichiers, combinez le 'find' avec l'éditeur de votre choix ('vim' dans mon cas). Pour éditer tous les fichiers texte (*.txt) du répertoire courant, utilisez :
% vim `find . -iname "*.txt"`Dans 'vim' ou 'vi', tapez
:npour passer au fichier suivant, ou
:wnpour sauvegarder les changements et passer au fichier suivant.
Pour annuler les changements et passer au fichier suivant, utilisez :
:n!Et enfin, pour quitter avant que la liste entière des fichiers ait été éditée :
:q!
Pour chercher tous les fichiers dont le nom correspond à un modèle de nom de fichier ET qui contiennent un texte particulier, utilisez ce qui suit.
Par exemple, pour chercher tous les fichiers texte (*.txt) qui contiennent le terme "memo", puis les éditer avec 'vim' :
vim `find . -type f -iname "*.txt" -print0 | xargs -0 grep -ilw "memo"`
Si vous visualisez un fichier avec 'less', et que vous décidez ensuite de l'éditer, tapez juste 'v'. Cela vous emmenera dans l'éditeur 'vi', pré-chargé avec le fichier que vous êtes en train de consulter.
Si 'vi' n'est pas de votre goût, modifiez la variable d'environnement VISUAL de façon à définir l'éditeur qui sera utilisé.
% setenv VISUAL vimVous pouvez faire la même chose avec 'more', sauf que vous devrez modifier la variable d'environnement EDITOR à la place. Notez que 'less' utilisera EDITOR si VISUAL n'est pas définie.
Si votre session Terminal est corrompue, par exemple après avoir accidentellement édité ou affiché un fichier binaire, utilisez 'tput'.
% tput resetpour faire un reset du Terminal, ou
% tput initpour l'initialiser.
La difference entre les deux dépend repose sur la différence entre les chaînes 'reset' et 'init' du Terminal situées dans la base de données 'terminfo' (/usr/share/terminfo/....). Mac OS X utilise la terminfo plutôt que la termcap. Terminfo est une base de données compilée et pour pouvoir en voir le contenu vous devez utiliser 'infocmp terminal-name'.
Par exemple :
% infocmp vt100
Nettoyer un fichier avec 'tr' et 'sed'.
La commande suivante retire les espaces et les lignes blanches en trop et change les fins de ligne au format Mac en des fins de lignes au format Unix.
% tr -s " " < test.txt | tr \r \n | sed '/^$/d' > out.txtLe fichier en entrée est test.txt et celui en sortie est out.txt
A propos des Expressions Régulières
Les 'RE' suivent trois tendances : le vieux style 'basique' ou 'obsolete' tel que reconnu par 'grep', 'sed', 'vi', ...; le style 'étendu' ou compatible-POSIX tel que reconnu par egrep, gawk, PHP, ...; et les expressions régulières Perl reconnues par Perl et PHP.
Perl est plus puissant que POSIX qui est à son tour plus puissant que le Basic.
Des incompatibilités existent entre les différentes variétés, tout un chacun devra donc vérifier quelle forme utilisée avec un utilitaire donné.
Par défaut, la recherche s'effectue ligne à ligne et est sensible à la casse.
Les astuces de cette semaine vont se concentrer sur les "RE" de style POSIX.
Correspondance et Echappement avec les 'ER' POSIX
% cat test
Ceci est un fichier test
pour illustrer l'utilisation des
expressions régulières.
Voici un symbôle $ dollar.
Ceci est la fin du fichier.
Pour rechercher une chaîne simple :
% egrep "Ceci" testVous devez rendre explicitement la recherche insensible à la casse : la méthode dépendra de l'utilitaire que vous utilisez. Pour 'egrep' utilisez l'option -i.
Les caractères qui ont un sens spécial au sein des expressions régulières doivent être échappés pour dire "prend litéralement le caractère et ignore tout autre sens spécial qu'il pourrait autrement avoir".
Les caractères spéciaux qui doivent être échappés sont :
. ^ $ * + ? [ ( ) | {Par exemple :
% egrep "$ dollar" testUtilisez des guillemets pour éviter que le shell interprête le signe $.
Notez qu'il n'est pas toujours nécessaire d'échapper les caractères spéciaux car ils peuvent n'être spéciaux que dans des contextes particuliers, mais il est quand même préférable de le faire tout le temps.
% egrep 'symbôle $ dollar' test
Une ancre est utilisée pour forcer le modèle à correspondre soit avec le début soit avec la fin d'une ligne.
% cat testLa recherche de 'ceci' ou de 'ligne' retournera les deux lignes du fichier :
Utilisez '^' pour ancrer le modèle sur le début d'une ligne :
% egrep '^ceci' testUtilisez '$' pour ancrer le modèle sur la fin d'une ligne :
% egrep 'ligne$' test
Le caractère spécial '.' correspondra à n'importe quel caractère.
Pour trouver b
Ces caractères spéciaux précisent que le caractère précédent est répété un certain nombre de fois :
Enfin :
'Hello.*goodbye' correspondra à Hello<0 ou plusieurs caractères quelconques>goodbye
Utilisez les rangées pour chercher un nombre spécifique de caractères.
Rechercher une Série de Caractères
Les astuces de cette semaine sont la suite de la série initiée la semaine dernière sur les Expressions Régulières (ER) POSIX.
Rechercher n'importe quel caractère compris dans une série en utilisant une expression entre crochets (une série de caractères délimitée par []).
% egrep 'b[aeiou]g'trouvera bag, beg, big, bog, et bug.
Inverser la recherche en commençant la séquence par le caractère '^'.
% egrep 'b[^aeiou]g' filetrouvera bbg, bcg, ... bzg, mais pas bag, beg, etc.
Rechercher une série de caractères consécutifs en utilisant un tiret comme dans [a-z] pour tous les caractères minuscules ou [0-9] pour les chiffres. Par exemple:
% egrep '^[a-zA-Z]{3}[0-9]{2}$' filetrouvera 'lettre lettre lettre chiffre chiffre' ancré au début et à la fin de la ligne (voir les astuces de la semaine dernière sur les ancres et les répétiteurs {}).
Une classe de caractère est un nom appliqué à un ensemble particulier de caractères, enfermé dans :class-name: et utilisé dans une expression entre crochets.
[:alpha:] recherche tous les caractères alphabétiquesLes classes sont :
alnum digit punctLes classes de caractères fonctionnent en PHP et en Perl, mais ne semblent pas fonctionner avec egrep sous OS X 10.2.
Il n'est pas nécessaire (en fait, c'est incorrect) d'échapper les caractères spéciaux ^ $ * + ? [ ( ) | { dans un expression entre crochets (voir astuce de Lundi).
Pour faire correspondre un '^' assurez-vous qu'il n'est *pas* le premier caractère de la liste (sinon, il inversera la correspondance) et pour faire correspondre ']' assurez-vous qu'il *est* le premier caractère de la liste.
% egrep '[]%$^]' filecorrespond à un des ] % $ ^
Aucune correspondance avec ci-dessus avec :
% egrep '[^]%$^]' fileNotez qu'il est permis d'échapper des caractères spéciaux dans des expressions entre crochets en utilisant Perl ou des expressions compatibles Perl en PHP.
Tester des Expressions Régulières
La façon la plus simple de tester une expression régulière est d'utiliser 'egrep' et l'entrée standard.
% egrep 'egrep lira l'entrée standard (aucun nom de fichier fourni). Tapez une ligne de texte. Si l'expression régulière correspond, la ligne de texte sera réaffichée, sinon elle ne le sera pas.
Visualisation des Fichiers Logs
Cette semaine et la semaine prochaine, je vais aborder ce qui concerne les fichiers logs, de leur consultation à la configuration du démon de logging.
La plupart des fichiers log résident dans '/var/log', y compris le fichier log principal du système et les fichiers logs des démons netinfo et lookup. Si vous avez activé des services mail, ftp et impression, vous verrez leur fichier log ici aussi. Les informations générales et critiques en rapport avec mail sont écrites dans le fichier log système.
Visualiser des fichiers log en utilisant 'tail' (system.log dans l'exemple), de façon statique en tapant :
% tail -n35 /var/log/system.log'-n35' est utilisé pour montrer les 35 dernières lignes au lieu des 10 dernières par défaut.
Visualiser des fichiers log de façon dynamique en tapant :
% tail -n35 -f /var/log/system.logPressez control-c pour stopper 'tail' et revenir à la ligne de commande.
La commande :
% tail -n35 -f /var/log/system.log &va constamment interrompre l'écran de votre Terminal avec les entrées les plus récentes du fichier log et va finir par vous irriter :-)
Pour l'arrêter, tapez :
% kill nnnoù nnn est le numéro que vous aviez noté précédemment.
Jetez un oeil dans /var/log. Vous remarquerez que les fichiers log sont archivés périodiquement : quotidiennement pour le fichier log système et hebdomadairement pour les autres. Cela se traduit par la création d'une archive à partir du fichier log le plus récent en
Vous pouvez visualiser les anciens fichiers log sans avoir à les décompresser et à les compresser de nouveau en utilisant 'zcat'.
% zcat /var/log/system.log.0.gz | tail -n35Créez un alias afin d'avoir un raccourci pratique pour consulter les fichiers logs :
alias tlog 'tail -f -n35 /var/log/!:1.log'permettant à quiconque de taper :
% tlog systemplutôt que :
% tail -n35 -f /var/log/system.log
Si vous avez lancé 'apache', ou 'named' ou tout autre démon créant des fichiers log, vous pouvez les archiver (voir l'astuce de Mardi) vous-même avec un simple script placé dans /etc/weekly.local. 'apache' and 'named' écrivent leurs fichiers log dans un sous-répertoire de /var/log, et donc les fichiers log ne sont pas archivés par les scripts standard hebdomadaires.
Si /etc/weekly.local n'existe pas créez le tel quel :
4.0k -r-xr-xr-x 1 root wheel 973 Nov 1 14:01 weekly.localLe script ressemblera à cela :
#!/bin/sh -
################################## # Local weekly tidy-up script # ##################################
host=$(hostname -s) echo "Subject: $host Local weekly run output"
for logtype in httpd named do
echo "" echo -n "Rotating type $logtype log files:"
if [ -d /var/log/$logtype ]; then cd /var/log/$logtype for log in *.log do echo -n " $log" if [ -f "${log}.3.gz" ]; then mv -f "${log}.3.gz" "${log}.4.gz"; fi if [ -f "${log}.2.gz" ]; then mv -f "${log}.2.gz" "${log}.3.gz"; fi if [ -f "${log}.1.gz" ]; then mv -f "${log}.1.gz" "${log}.2.gz"; fi if [ -f "${log}.0.gz" ]; then mv -f "${log}.0.gz" "${log}.1.gz"; fi if [ -f "${log}" ]; then mv -f "${log}" "${log}.0" /usr/bin/gzip -9 "${log}.0" fi touch "$log" done
case $logtype in httpd) apachectl graceful;; named) ndc restart;; *);; esac
fi
done
echo "" echo "Complete"
Notes :
Cette ligne spécifie le sous-répertoire de /var/log qui sera archivé :
for logtype in httpd namedCes lignes redémarrent chaque démon pour être sûr qu'ils reconnaîtront le nouveau fichier log :
httpd) apachectl graceful;;'ndc restart' peut ne pas fonctionner sous Panther car il utilise une version différente de 'bind' vers Jaguar.
Les messages d'erreurs et les messages critiques du noyau et de messagerie sont écrits sur la Console (certains vont aussi dans le fichier log système). La Console est un périphérique situé dans /dev/console, et tout ce qui y est écrit est envoyé vers le fichier /var/tmp/console.log.
Consulter la Console avec :
% tail -n35 /var/tmp/console.logou
% tail -n35 -f /var/tmp/console.logLe log de la Console peut aussi être consulté avec Console.app située dans /Application/Utilities.
Les messages log du kernel, en particuliers ceux provenant des pilotes de périphériques, sont écrits dans le buffer des messages système au lieu des fichiers log.
Consulter le buffer des messages système avec :
dmesgSi vous avez des problèmes au démarrage ou des problèmes avec un périphérique, 'dmesg' pourra être une source intéressante pour obtenir des informations utiles au déboguage.
Cette semaine, nous poursuivons sur le thème du logging initié semaine 61.
Les applications Unix effectuent des entrées log via le 'system logger' : 'syslogd'. Chaque entrée log porte sur des outils tels que 'mail', 'syslog', ou cron', et sur des niveaux allant de l'urgence au déboguage.
Syslogd filtre les messages et les dirige vers des fichiers log particuliers en fonction de leur provenance ou de leur niveau, et de sa propre configuration. (Voir Mardi.)
Les outils sont :
auth, authpriv, cron, daemon, kern, lpr, mail, mark, news, syslog, user, uucp et local0 jusqu'à local7Les niveaux sont :
emerg, alert, crit, err, warning, notice, info et debug Changer la Configuration de Syslogd
Le démon syslogd enregistre les messages en fonction de leur provenance et de leur niveau (voir Lundi) et de sa propre configuration située dans /etc/syslog.conf.
Changez ce qui est enregistré et où ce sera enregistré en modifiant /etc/syslog.conf. Redémarrez syslogd et les démons correspondants pour vérifier que les changements soient perçus. Redémarrez la machine si des changements plus importants sont effectués.
Chaque ligne consiste en une liste de paires "outil.niveau" et d'une destination. Toutes les entrées log qui incluent un outil listé et un niveau d'erreur correspondant ou supérieur seront envoyées vers la destination. '*' est un joker avec son sens habituel.
Pour envoyer les messages vers un autre hôte, utilisez @hostname comme destination donnée dans /etc/syslogd. L'hôte destinataire doit avoir un syslogd démarré avec l'option -u. Les messages log sont envoyés sur le port UDP 514.
Notez que cela représente une vulnérabilité pour une attaque extérieure compte tenu qu'un pirate pourrait écrire en continue dans vos fichiers log.
La commande 'logger' peut être utilisée pour enregistrer manuellement des messages log comprenant l'outil d'origine et la priorité. Cela est utile pour tester une nouvelle configuration de 'syslogd'.
Ecrivez dans le fichier log de mail avec le niveau 'info' :
logger -p mail.info Message log de test ici...Diffuser un message d'urgence à tous les utilisateurs connectés :
logger -p user.emerg Urgence...
Changez le schéma de logging du démon ftp (ftpd).
Tapez :
cat /etc/syslog.conf ~ % cat /etc/syslog.conf
*.err;kern.*;auth.notice;authpriv,remoteauth.none;mail.crit /dev/console *.notice;*.info;authpriv,remoteauth,ftp.none;kern.debug;mail.crit /var/log/system.log
# The authpriv log file should be restricted access; these # messages shouldn't go to terminals or publically-readable # files. authpriv.*;remoteauth.crit /var/log/secure.log
lpr.info /var/log/lpr.log mail.* /var/log/mail.log ftp.* /var/log/ftp.log netinfo.err /var/log/netinfo.log
*.emerg *
Remarquez la ligne :
ftp.* /var/log/ftp.log
qui indique que pour l'outil ftp tous les niveaux (indiqué par "*") seront envoyés vers ftp.log.
Changez /var/log/ftp.log pour envoyer les messages vers un fichier différent.
Cette ligne :
*.notice;*.info;authpriv,remoteauth,ftp.none;kern.debug;mail.crit /var/log/system.log
exclut spécifiquement les messages ftp du log système en spécifiant 'ftp.none'
Changez en 'ftp.*' pour faire en sorte que le démon enregistre les messages log dans le log système.
Cette ligne :
*.err;kern.*;auth.notice;authpriv,remoteauth.none;mail.crit /dev/console
spécifie que les niveaux 'err' et supérieurs de tous les outils ('*') (incluant ainsi ftp) sont envoyés vers la console.
Le log de la console peut être visualisé par Console.app, ou en consultant /var/tmp/console.log.
Les connexions ftp sont de deux sortes :
Actives - avec ce mode, le serveur contacte le client pour lui transférer des données. Le client doit avoir les ports appropriés ouverts dans son firewall.
Passives - avec ce mode, le client contacte toujours le serveur et n'a donc pas besoin de ports ouverts. Le mode passif est le mode par défaut.
Si vous souhaitez utiliser le mode actif, ou trouvez que le mode passif a tendance à raccrocher, oouvrez un port dans le firewall avec :
% sudo ipfw add 2300 allow tcp from any 20,21 to any 1024-65535 in(Le numéro de rôle, 2300 dans cet exemple, ne doit pas entrer en conflit avec des numéros de rôle existants).
Cela autorisera votre client à utiliser le ftp actif mais ne transformera pas votre Mac en serveur ftp.
Le umask par défaut (autorisations des fichiers créés) positionné par le démon ftp est 027, ce qui signifie qu'il n'y a pas de permissions en lecture pour les autres sur les fichiers que vous envoyez. Si vous souhaitez changer ceci, par exemple pour permettre à Apache d'accéder aux fichiers que vous avez chargés, paramétrez alors le umask :
ftp> site umask 022Cela n'affecte que la session actuelle.
La solution umask de Mardi affecte seulement la session ftp dans laquelle elle est utilisée. Pour un effet permanent, à chaque connexion, vous devez configurer le démon ftp.
Editez le fichier /etc/ftpd.conf (ou créez le) - vous devez le faire en étant l'utilisateur (super) root.
Ajoutez la ligne :
umask all 022
Le démon ftp envoie ses messages de log dans /var/log/ftp.log
Si vous souhaitez inclure des informations supplémentaires dans le fichie log alors relancez le démon ftp avec l'option -d.
Editez le fichier :
/etc/xinetd.d/ftpet ajoutez le debug ou toute autre option sur la ligne
server_args = -l
Tout propriétaire de compte Unix peut se servir de ftp dans un serveur. Pour empêcher un utilisateur particulier de se servir de ftp ajoutez son nom de compte à :
/etc/ftpusersPour créer un utilisateur qui ne peut pas se connecter mais peut lancer ftp réglez son shell sur :
/sbin/nologinet assurez-vous que ce shell est listé dans :
% cat /etc/shellsEnfin, pour stopper un utilisateur ftp dans son exploration de ce qui se trouve hors de son répertoire de départ, faites un 'chroot' sur eux. Ajoutez leur nom de compte à :
/etc/ftpchrootRemarquez que cette fonction est cassée dans OS X 10.2. Une alternative consiste à installer un nouveau démon ftp tel qu'un pure ftp. Reportez à ce fil de discussion :
Comment installer un pur FTP
La maintenance périodique du système est programmée par 'cron' (voir Semaine 33). Cron lance un programme appelé 'periodic' qui a la responsabilité de lancer les scripts de maintenance.
% cat /etc/crontab ... #minute hour mday month wday who command # Run daily/weekly/monthly jobs. 15 3 * * * root periodic daily 30 4 * * 6 root periodic weekly 30 5 1 * * root periodic monthly ...
Le script quotidien est lancé à 3:15 am.
Le script hebdomadaire à 4:30 le Samedi.
Le script mensuel est lancé à 5:30 le premier de chaque mois.
Votre Mac doit tounrer (ne pas être en sommeil) pour que ces scripts puissent être lancés.
Le produit de ces scripts peut être trouvé dans :
% ls /var/log/*.out
Si votre Mac n'est pas éveillé à des heures matinales (voir l'astuce de Lundi), vous devrez lancer les scripts de maintenance manuellement. Cela se fait ainsi :
% sudo periodic dailyAutrement, éditez /etc/crontab et choisissez des heures durant lesquelles votre Mac sera actif.
Ou, servez vous du freeware MacJanitor
http://macupdate.com/info.php/id/5856
Si vous souhaitez ajouter vos propres taches de maintenance - quotidienne, hebdomadaire ou mensuelle - alors créez les fichiers suivants si nécessaire.
/etc/daily.localCe sont des scripts shell réguliers et sont lancés automatiquement, une fois créés, par les scripts quotidien, hebdomadaire et mensuel par défaut.
Les scripts lancés par 'periodic' pour les taches de maintenance quotidiennes, hebdomadaires et mensuelles sont localiés dans :
# ls /etc/periodic/*Periodic peut être appelé avec un chemin d'accès complet vers un répertoire (au lieu des termes daily, weekly ou monthly), et il lancera tous les scripts situés dans ce répertoire.
Periodic est configuré par le fichier :
/etc/defaults/periodic.confVous pouvez ajouter votre propre réglage et les placer dans le fichier :
/etc/periodic.confReportez-vous à 'man periodic.conf' pour plus d'informations.
Ce script peut être placé dans /etc/weekly.local. Il archivera de façon circulaire (nombre de fichiers constant, le plus ancien laissant place au plus récent), mieux que ne le fait le script quotidien standard. Le script standard n'archive que les fichiers *.log qui sont dans /var/log. Ce script fait la même chose pour des sous-répertoires tels que /var/log/httpd/*.log et /var/log/bind/*.log.
#!/bin/sh -
########################## # Script quotidien de nettoyage # ##########################
host=$(hostname -s) echo "Sujet: $host - rapport du lancement quotidien en local"
# liste les sous-répertoires à considérer, dans ce cas # /var/log/httpd and /var/log/named for logtype in httpd named do
echo "" echo -n "Archivage des fichiers log de type $logtype :"
if [ -d /var/log/$logtype ]; then cd /var/log/$logtype for log in *.log do echo -n " $log" if [ -f "${log}.3.gz" ]; then mv -f "${log}.3.gz" "${log}.4.gz"; fi if [ -f "${log}.2.gz" ]; then mv -f "${log}.2.gz" "${log}.3.gz"; fi if [ -f "${log}.1.gz" ]; then mv -f "${log}.1.gz" "${log}.2.gz"; fi if [ -f "${log}.0.gz" ]; then mv -f "${log}.0.gz" "${log}.1.gz"; fi
if [ -f "${log}" ]; then mv -f "${log}" "${log}.0" /usr/bin/gzip -9 "${log}.0" fi touch "$log" done
case $logtype in httpd) apachectl graceful;; named) ndc restart;; *);; esac
fi
done
echo "" echo "Fin de traitement"
Nom de fichiers avec des Espaces
Les noms de fichiers avec des espaces peuvent poser problèmes dans les scripts. (Voir semaine 51 pour des exemples.)
Lors du traitement de tous les fichiers d'un répertoire avec une boucle 'for', utilisez '*' au lieu de '`ls`'. Par exemple:
bash$ ls -1
Bash évaluera une expression arithmétique enfermée par $((...))
bash$ n1=3; n2=4; n3=5Cela ne marchera pas :
bash$ n="(($n1+$n2)*$n3)"Mais cela marchera :
bash-2.05a$ n=$(( ($n1 + $n2) * $n3 ))Ou alors, utilisez des $((...)) imbriqués :
bash$ n=$(( $(( $n1 + $n2 )) * $n3 ))
Bash permet à quelqu'un de 'déclarer' des variables shell. Un des avantages de telles déclarations tient dans le fait qu'on peut leur donner des attributs spécifiques.
Déclarez une variable en lecture seule :
bash$ declare -r pi=3.14Les variables peuvent aussi être marquées comme étant des entiers, auquel cas bash appliquera des évaluations arithmétiques sans l'aide de $((...)) (voir Mardi):
Cela marchera :
bash$ declare area1Mais en utilisant 'declare -i', cela marchera aussi :
bash$ declare -i area2 Valeurs par Défaut des Paramètres
Supposez que vous souhaitiez appliquer la valeur de $1 à une variable si $1 est donné, ou une valeur par défaut dans le cas contraire.
Cela peut être accompli avec :
#!/bin/bash #positionne level à $1, ou à la valeur 5 si $1 n'est pas donnée if [ "$1" == "" ]; then level=5 else level=$1 fi
Ou plus simplement :
level=${1:-5}
La commande printf est beaucoup plus puissante que echo. Elle prend comme argument une chaîne de formattage et un ensemble d'arguments à afficher dans le contexte de cette chaîne de formattage.
Cette instruction affichera une ligne, indenté d'un nombre calculé de caractères, l'intitulé étant aligné à droite et la première valeur étant en rouge.
bash$ cat tst
#!/bin/bash
declare -r norm="33[00m" red="33[31m"
declare -i indent=${3:-4}
declare -i spacer=20-$indent
printf "%${indent}s%-${spacer}s${red}%7d,${norm}%7dn" " " "Valeurs:" $1 $2
bash$ tst 1234 5678
Valeurs: 1234, 5678
bash$ tst 1234 5678 8
Valeurs: 1234, 5678
La variable d'environnement PS1 contient le prompt primaire du shell bash.
Changez le avec, par exemple :
$ declare -x PS1="host=h$ "h est remplacé par le nom d'hôte jusqu'au premier '.'. $ est remplacé par '$' pour les utilisateurs normaux et par '#' pour root.
Cette exemple affichera le nom de l'utilisateur courant et l'heure actuelle en rouge :
$ declare -x PS1="e[31mu-Ae[0m$ "D'autres possibilités (tirées du manuel bash)
a un caractère clôche ASCII (07) d date sous la forme "Jourdelasemaine Mois Date" e un caractère ASCII d'échappement (033) h le nom d'hôte jusqu'au premier `.' H le nom d'hôte j nombre de jobs actuellement gérés par le shell l nom de base du terminal du shell n nouvelle ligne r retour charriot s nom du shell, basename de $0 t heure (0-23) au format HH:MM:SS T heure (0-11) au format HH:MM:SS @ heure (0-11) au format am/pm A heure (0-23) au format HH:MM u le nom de l'utilisateur actuel v la version de bash (ex : 2.00) V version de bash, version+niveaudepatch w le répertoire actuel de travail W nom de base du répertoire actuel ! le n° de la commande dans l'historique # nbre de fois que la commande a été tapée $ a # pour root , sinon a $ nnn caractère avec nombre nnn octal \ un backslash [ début de caractères non imprimables ] fin de caractères non imprimables
Créez un fichier nommé '.bash_profile' à la racine de votre répertoire départ. Ce fichier sera exécuté lorsque bash sera invoqué en tant que shell de connexion (lorsque vous démarrez une nouvelle session Terminal avec Terminal.app). Placez ici les réglages qui seront passés aux sous-shells - ex : paramétrez des variables d'environnement telles que PS1 (voir l'astuce de Lundi) et le PATH de recherche.
Ajoutez aussi la ligne :
. .bashrcCela exécutera le second fichier de démarrage.
Créez un second fichier nommé '.bashrc' à la racine de votre répertoire départ. Ce fichier sera exécuté lorsque shell sera invoqué comme shell de non-connexion (quand vous tapez 'bash' pour démarrer un sous-shell). Si vous avez ajouté la ligne '. .bashrc' à '.bash_profile', '.bashrc' sera alors excuté pour tous les shells (de connexion et de non-connexion) interactifs. Placez tous les autres réglages dans '.bashrc'.
Si vous souhaitez changer temporairement de répertoire, et souhaitez revenir au répertoire d'origine, utilisez 'pushd' au lieu de 'cd'. 'pushd' passe au nouveau répertoire mais enregistre le répertoire d'origine. 'popd' retourne au répertoire d'origine.
Par exemple:
$ pwd
Par défaut, une session Terminal enregistre les 500 dernières commandes dans son historique. Si vous avez l'habitude de laisser votre Terminal ouvert pendant de longues périodes et que vous souhaiteriez disposer de plus d'historique (disons 2000 commandes), ajoutez ceci au fichier '.bash_profile' (voir astuce de Mardi).
declare -x HISTSIZE=2000;Il est judicieux d'augmenter la taille du fichier historique aussi.
declare -x HISTFILESIZE=2000;Si vous avez plus d'une session Terminal ouverte alors pour empêcher l'écrasement du fichier historique par la dernière session, régler l'option de fusion d'historique dans '.bashrc'
shopt -s histappendCela fera en sorte que les hostoriques de différentes sessions seront fusionnés.
Si vous souhaitez que la fonction de remplissage automatique des noms de fichier ignore la casse, par exemple :
$ ls ~/docsera complété par :
$ ls ~/Documents/alors, créez un fichier appelé '.inputrc' à la racine de votre répertoire départ et ajoutez la ligne :
set completion-ignore-case onEn plus, pour faire en sorte que la fonction de remplissage automatique liste immédiatement des alternatives (bash fait d'abord sonner une clôche) ajoutez la ligne :
set show-all-if-ambiguous on Ouvrir des Fichiers et des Dossiers
Utilisez la commande 'open' pour simuler un double-clic dans le Finder.
Voici quelques exemples d'utilisation.
Ouvrir un dossier dans une fenêtre du Finder :
% open SitesOuvrir un document avec son application par défaut :
% open Sites/index.htmlOuvrir un document avec une autre application :
% open -a /Applications/Internet Explorer.app Sites/index.htmlOuvrir de multiples dossiers/documents/applications d'un seul coup :
% open *.html pic1.jpeg pic2.jpeg ...
Lancer des applications GUI, à la fois Cocoa et Carbon, en utilisant 'open'.
Ouvrez une application :
% open /Applications/Safari.appLancer une application Cocoa manuellement, par exemple sans se servir d'open.
% /Applications/Safari.app/Contents/MacOS/Safari &Le '&' placé à la fin de la commande va lancer Safari sous forme de process séparé vous permettant de continuer à utiliser le shell en cours.
Le lancement manuel peut être plus rapide dans des scripts. Il peut aussi être utilisé pour lancer de multiples copies d'une application là où le Finder (et 'open') ne le ferait pas.
Lancer des Applications en tant que Root
Utilisez la commande 'sudo' pour lancer une application en tant que root.
L'utilisation de 'sudo open' ne marchera pas, car 'open' est exécutée en tant que root mais pas l'application qu'elle lance. On doit la lancer manuellement (voir l'astuce de Mardi).
% sudo -b open /Applications/Clock.app/ % ps -auxc | grep "[C]lock" saruman 2405 ... 0:00.57 Clock
(Clock est lancé sous l'utilisateur 'saruman', PAS sous root.)
% sudo -b /Applications/Clock.app/Contents/MacOS/Clock % ps -auxc | grep "[C]lock" saruman 2405 ... 0:00.72 Clock root 2410 ... 0:00.36 Clock
(Le second Clock est exécuté sous root.)
Ne JAMAIS utiliser 'sudo', ou faire quoi que ce soit sous root, lorsque vous avez bu trop de bières. Cela s'applique particulièrement à aujourd'hui :-)
Joyeux Noël.
Lancez une application Carbon manuellement (dans cet exemple, Internet Explorer).
% /System/Library/Frameworks/Carbon.framework/Versions/(Notez qu'il n'y a pas de retour-charriot dans cette commande)
Les applications Carbon ne sont pas dans le format binaire correct pour Mac OS X. Elles doivent être lancées par 'LaunchCFMApp', qui s'occupe de la magie nécessaire.
Sur les systèmes antérieurs à Panther, vous pouvez remarquer que l'utilisation de l'option '-c' avec la commande 'ps' affiche LaunchCFMApp à la place de l'application elle-même. Cela provoque l'échec de scripts et de commandes telles que 'killall'.
Lancer une Application Carbon en tant que root en utilisant :
% sudo echoLa ligne 'sudo echo' contourne les problèmes de saisie de mot de passe.
Les astuces de cette semaine s'appliquent à la fois aux paramètres de script bash tels que $1 et aux variables shell telles que $my_var. Dans les exemples de code, j'ai utilisé une variable shell.
Positionner la valeur d'une variable shell soit sur celle d'une autre variable ou paramètre, soit sur celle par défaut si l'autre variable ou paramètre n'est pas positionné.
$ echo $testJ'ai utilisé 'echo' pour illustrer l'extension, mais on devrait normalement l'assigner à une variable :
$ var=${test:-not-set}Dans le prochain exemple, la variable 'test2' n'est pas positionnée et donc la valeur par défaut s'y substitue.
$ echo ${test2:-not-set}Notez que test2 reste non positionnée jusqu'à ce qu'on utilise ':=' à la place de ':-'.
$ echo ${test2:=not-set} Erreur sur Variables sans Valeur
Faites en sorte que bash rapporte une erreur si une variable ou un paramètre n'a pas de valeur.
$ echo ${test3:?}Ecrivez un message d'erreur personnalisé avec :
$ echo ${test3:?it is not set}Une erreur est rapportée si une variable n'existe pas, comme ci-dessus, ou est valorisé à null (rien) :
$ test4=
Prenez une tranche d'une variable.
$ echo $testLe premier exemple extrait une tranche à partir du cinquième caractère (le premier étant le caractère 0) et le second extrait deux caractères à partir du cinquième.
Déterminez le nombre de caractères de la valeur d'une variable.
$ echo ${#test}
Tronçonner la tête ou le pied d'une variable.
$ echo $testCet exemple recherche un modèle à partir du début de la variable ("/hell") et le tronçonne à partir de là :
$ echo ${test#/hell}Il est permis d'utiliser des jokers "*" pour faire correspondre 0 ou plus d'occurences de n'importe quel caractère.
$ echo ${test#*l}Dans l'exemple précédent la chaîne la plus petite qui correspond à '*l' a été tronçonnée ('/hel'). Dans le suivant, l'utilisation d'un double # correspond à la chaîne la plus longue ('/hello/worl').
$ echo ${test##*l}Extrayez juste le nom du script à partir du nom complet contenu dans le paramètre 0. Cela devrait être effectué dans un script bash.
En supposant que $0 est /usr/local/bin/script
scriptname=${0##*/}donne :
scriptUtilisez % à la place de # (et %% à la place de ##) pour tronçonner à partir de la fin de la chaîne.
$ echo ${test%/*}
Chercher et remplacer une valeur dans une variable.
Pour chercher la première occurence de 'hello' et la remplacer par 'goodbye':
$ echo $testPour remplacer toutes les occurences d'un modèle, utilisez '//'.
$ echo ${test/l/L}Utilisez # pour ancrer le modèle au début de la chaîne et % pour l'ancrer à la fin.
$ echo ${test2/#d/D}
Voir dans les semaines précédentes les astuces sur vim.
Rechercher dans un fichier un texte en particuler, tel que 'transform'. En mode normal (pressez la touche echappement pour sortir du mode insertion) type:
/transformSi vous avez besoin d'une recherche sur un mot complet, de façon à ce que 'transformations' ne soit pas retenu, tapez :
/Pour rechercher en arrière, utilisez :
?transformPour rechercher l'occurence suivante, tapez 'n' et 'N' pour la précédente.
Pour rappeler une précédente recherche, tapez '/' puis pressez la touche "flèche vers le haut" jusqu'à tomber sur la chaîne à rechercher.
Remplacer une erreur de frappe telle que 'teh' par 'the' en utilisant "chercher et remplacer" :
:%s/teh/the/g'%' veut dire toutes les lignes du fichier et 'g' veut dire toutes les occurences de chaque ligne.
Remplacer '%' par une rangée d'adresse telle que '.,$' qui effectue le remplacement à partir de la ligne courante (ligne .) jusqu'à la fin du fichier (ligne $).
Pour rappeler un précédent rechercher-remplacer tapez "/" et pressez la touche "flèche vers le haut" jusqu'à atteindre l'occurence souhaitée.
Utilisez des expressions régulières dans les recherches vim. Voir semaines 59 et 60 pour plus d'informations sur les expressions régulières.
Chercher une ligne commençant par 'The' :
/^TheRemplacer 'chapter
La construction (...) capture le texte placé dans le modèle, tandis que 1 le rejoue dans dans la chaîne remplacée.
Rendez les recherches sensibles à la casse avec :
:set ignorecaseMaintenant, le modèle /the marchera pour The, the et THE
Avec "smartcase", les modèles entièrement en minuscule s'applique de manière insensible à la casse, tandis que les modèles comprenant des majuscules s'appliquent en étant sensible à la casse :
:set smartcaseLe modèle /the marche pour The, the et THE
mais le modèle /The ne marche que pour The
Mettez en évidence toutes les occurences trouvées en tapant :
:set hlsearchet désactivez la mise en évidence avec :
:set nohlsearchet utilisez :
:noh[ighlight]pour désactiver temporairement la mise en évidence actuelle.
Trouver l'occurence suivante du mot qui se trouve sous le curseur. En mode normal tapez '*' ou '#' pour rechercher vers le haut. Seules les mots entiers seront trouvés à moins que vous n'utilisiez 'g*' ou 'g#'.
Pour rechercher la prochaine occurence tapez 'n' et 'N' pour la suivante.
Utilisez des commandes globales pour rechercher les lignes à éditer. Pour effectuer un 'Rechercher Remplacer', seulement sur les lignes qui commencent par 'edit', utilisez :
:g/^edit/s/hello/Goodbye/gLa forme générale de cette commande est :
g/search-pattern/command'search-pattern' est une expression régulière et 'command' est une commande 'ex'. la forme est identique à celle utilisée par 'sed'.
Pour plus d'informations sur les commandes disponibles, utilise :
man exPour supprimer toutes les lignes qui commencent par '.', utilisez :
:g/^./dLa commande 'd' supprime la ligne.
Pour sélectionner toutes les lignes qui ne correspondent pas au modèle, utilisez 'g!' au lieu de 'g'.
Pour utiliser les commandes du mode normal de vim à la place des commandes 'ex', utilisez :
g/search-pattern/normal vim-command-listCet exemple ajoutera '...' à toutes les lignes qui contiennent 'edit'
:g/edit/normal A...
Déterminez le type d'un fichier, de part l'analyse de son contenu, en utilisant la commande 'file' :
$ file ~/bin/* add-user: Bourne-Again shell script text dhup: Bourne shell script text crontab: ASCII text nodif: Tenex C shell script text test: Mach-O executable ppc
$ file ~/sites/.../* data: directory images: directory include: directory index.php: C++ program text NOT QUITE! java-script: directory jf.html: HTML document text tc.html: HTML document text
Utilisation de la Commande File
Utilisez la commande 'file' en association avec d'autres commandes pour filtrer les types de fichier.
$ find . -print0 | xargs -0 -n1 fileVoir semaine 48, Vendredi en particulier.
Filtrez tous les fichiers au format texte riche en utilisant grep :
$ find . -print0 | xargs -0 -n1 file | grep -i "rich text"
Apportez de la précision à l'exemple de Mardi pour n'afficher que les noms de fichiers :
$ find . | xargs -n1 file | grep -i "rich text" | awk '{print $1}'Pour retirer le ':', dites à awk que le séparateur de champ est ':' :
$ find . | xargs -n1 file | grep -i "rich text" | awk -F: '{print $1}'Enfin, éditez touts les fichiers au format texte riche :
$ open -a textedit $(find . | xargs -n1 file | grep -i "rich text" | awk -F: '{print $1}')Dans le shell tcsh utilisez les apostrophes - `find ...` au lieu de $(find ...) .
Utilisez la commande 'hexdump' pour afficher le contenu d'un fichier binaire ou d'un fichier qui contient des caractères non affichables :
$ hexdump -n32 testLe fichier est affiché en hexadecimal, en se limitant aux 32 premiers octets (-n32).
On peut afficher en format caractère, avec les caractères non affichables soit en octal soit échappés (t = tab)... :
$ hexdump -n32 -c test...ou en caractère hexadecimal plus, avec des caractères non affichables représentés par un point :
$ hexdump -n32 -C testEssayez ceci :
$ hexdump -n4 /bin/*
Recherchez du texte ASCII dans un fichier binaire en utilisant la commande 'strings'.
a$ strings -a -16 /bin/ls'strings' recherche dans un fichier binaire des séquences de caractères affichables et les affiche. La longueur minimum par défaut est 4 mais elle peut être remplacée comme dans cet exemple. (option -16). Option -a recherche dans toutes les sections du fichier (par exemple, les fichiers exécutables ont des séctions pour le code et pour les données).
Utilisez la commande 'shopt' pour régler les options shell.
Pour régler :
$ shopt -sPour enlever le réglage :
$ shopt -uPour lister :
$ shoptQuelques options utiles sont indiquées ci-dessous.
(1) Utilisez 'cdspell' pour corriger les erreurs mineures de frappe dans les noms de fichier passés à 'cd':
$ cd DekstopMaintenant, réglez l'option shell 'cdspell':
$ shopt -s cdspell(2) Créez de courts alias pour de longs noms de répertoire :
$ shopt -s cdable_varsNote : n'utilisez pas l'alias '~' dans des variables 'cdable'.
Suite de l'astuce de Lundi :
(3) Autoriser le 'globbing' sensible à la casse :
$ ls -d d*Maintenant, autoriser la non sensibilité à la casse :
$ shopt -s nocaseglob(4) Incluer des fichiers point dans le 'globbing' :
$ ls -d * Desktop Documents Movies Pictures Sites osxfaq Development Library Music Public bin
Maintenant, autoriser le 'globbing' point :
$ shopt -s dotglob $ ls -d * .DS_Store .dir_colors .mplayer Desktop .FBCIndex .emacs.d .my.cnf Development .gimp-1.2 .mysql_history Documents .gvimrc ...
(5) Autoriser l'extension des chemins d'accès améliorés. En temps normal, seuls '*', '?' et '[...]' sont reconnus (comme dans 'ls *' ou 'ls file.???').
$ shopt -s extglobLe globbing étendu suivant est autorisé :
?(pattern-list) Recherche 0 ou 1 occurrence des modèles donnés
Faites en sorte que bash exécute une commande avant qu'il ne renvoit un prompt.
Pour afficher la date avant avant chaque prompt :
$ declare -x PROMPT_COMMAND='date'Ecrivez un message dans la barre de titre de la fenetre du Terminal (dans cet exemple, la sortie de la commande date) :
$ declare -x PROMPT_COMMAND='echo -n "^[]0; $(date)^G"'Notes :
^[ = échappement, obtenu en tapant contrôle-V puis escape.
^G = contrôle G, obtenu en tapant contrôle-V contrôle-G.
Cela fonctionne pour xterm et le Terminal d'Apple
Cela peut être utile :
$ declare -x PROMPT_COMMAND='echo -n "^[]0; $TITLE^G"'Maintenant, toute commande ou script exécuté peut afficher quelque chose dans la barre de titre en positionnant la variable d'environnement TITLE.
A l'inverse de tcsh, les alias bash n'acceptent pas les paramètres. Cela vient du fait que bash prodigue un mécanisme plus puissant de part des fonctions.
Ecrivez une fonction appelée 'word' qui effectue une recherche dans le dictionnaire Webster situé /usr/share/dict.web2 :
$ function word () { grep $* /usr/share/dict/web2; }$* s'applique à tous les paramètres passés à la fonction 'word'. $1 s'applique au paramètre 1, etc.
Pour lister toutes les fonctions, utilisez :
$ declare -f Développer la Commande 'alias'
Si vous souhaitez que la commande 'alias' liste toutes les fonctions (voi l'astuce de Jeudi), déclarez cette fonction :
function alias ()
{
if [ -z $* ] ; then
builtin alias;
declare -f;
else
builtin alias $* ;
fi
}
(Cette astuce provient d'un message posté par Kenneth dans le Learning Centre forum.)
Redirigez le texte vers l'entrée standard en utilisant les Documents Céans.
$ cat hdLa section entre '< Tout mot peut être utilisé comme délimiteur 'HereDoc', et la dernière ligne ne doit contenir que ce mot sans espace après.
Contrôlez l'extension d'une variable au sein d'un document céans. Les variables shell au sein d'un document HereDoc sont interprétées comme d'habitude : Mais si le délimiteur est entouré d'apostrophes, aucune interprétation de variable n'est effectuée :
Supprimez l'indentation des scripts shell dans les textes HereDoc. Les scripts élaborés comportent généralement des instructions indentées et il est naturel d'utiliser l'indentation. Pour permettre aux documents HereDoc de suivre une indentation naturelle, sans inclure de caractère tabulation dans le texte, utilisez '<<-'. Malheureusement, cela ne marche pas pour les scripts indentés par des espaces.
Utilisez un HereDoc et une fonction pour positionner des variables.
Merci à Ian Ferguson pour l'astuce de Vendredi. Utilisez des HereDocs pour commenter du code, évitant ainsi d'ajouter des "#" au début de chaque ligne : Ici, l'instruction 'if' a été commentée. Utilisez des HereDocs pour afficher un message d'erreur si une variable n'est pas positionnée :
Renommer un groupe de fichiers en une seule commande. Cela *ne* marchera *pas* : Le script suivant, appelé 'ext' pour 'basé sur l'extension', vous permettra d'y arriver : Utilisez 'ext' comme suit pour renommer (mv) *.html de façon à obtenir une extension du type .php : Utilisez toute commande similaire, telle que 'cp', dans le script 'ext'. Ajoutez une vérification de paramètre dans le script :
Renommer un groupe de fichiers de manière récursive en n'utilisant qu'une seule commande. Le script 'rext' fait la même chose que celui de l'astuce de Lundi sauf qu'il applique la commande à tous les fichiers sélectionnés dans la hiérarchie du répertoire. Il utilise le script 'ext'. Utilisez 'rext' comme suit pour copier (cp) *.php en leur équivallent avec l'extension .html : Utilisez toute commande similaire, telles que 'mv', avec le script 'rext'. Ajoutez une gestion de paramètre au script :
Si vous avez un script ou une commande qui soit incapable de prendre une liste de fichiers, utilisez le script 'each' pour simuler cela. 'each' exécute la commande donnée une fois par fichier. Utilisez le script ainsi pour appliquer 'my-script' à tous les fichiers .html du répertoire courant : Ajoutez une gestion de paramètre au script :
Le script 'reach' fait la même chose que le script de Mercredi, sauf qu'il exécute la commande donnée sur tous les fichiers correspondants de la hiérarchie du répertoire. Utilisez le script ainsi pour appliquer 'my-script' à tous les fichiers .php situés dans la hiérarchie du répertoire : Ajoutez une gestion de paramètres au script :
Créer une simple enveloppe pour la commande 'sed' (ou toute autre commande similaire) pour lui permettre de traiter directement un fichier. Normallement, sed utilise les sorties et entrées standard, et ne peut écrire dans son fichier entrée. Notez que la ligne la plus évidente : ne doit pas être utilisée ainsi compte tenu qu'une erreur dans le script sed provoquerait l'élimination de tous les fichiers. Utilisez sedx de cette manière : pour appliquer la commande sed à index.html. Le script tel qu'il est donné n'accepte qu'un seul fichier en entrée. Utilisez les scripts de Mercredi et de Jeudi pour traiter plusieurs fichiers. S'applique à tous les fichiers du répertoire courant : Ou à tous les fichiers de la hiérarchie du répertoire : Ajoutez une gestion de paramètres au script :
Les astuces de cette semaine sont en rapport avec l'application Terminal d'Apple (/Applications/Utilities/Terminal.app). Selectionner le mode scindé dans le Terminal en cliquant sur l'icône située dans le coin supérieur droit... On peut alors faire défiler la partie supérieure pour voir les commandes précédentes tandis que l'on travaille dans la partie basse. Cela permet de faire des copier-coller entre les deux cadres.
Copier du texte dans la fenêtre du terminal en le sélectionnant comme vous le feriez dans d'autres applications (clic gauche et glisser). Le texte sélectionné est automatiquement placé dans un buffer qui peut être rappelé en cliquant sur le bouton du milieu de la souris *. Pour coller du texte entre différentes fenêtres ou applications, utilisez la commande habituelle Commande-C (après avoir sélectionné le texte) pour copier, et Commande-V pour coller. Le Terminal supporte aussi le glisser-déposer sur di texte sélectionné. Deux utilitaires à ligne de commande sont prodigués pour copier et coller : (texte précédemment copié à partir d'une application dotée d'une interface utilisateur graphique) * Une souris à trois boutons est pratique lorsque l'on travaille dans le Terminal d'Apple ou dans xterm.
Créez un script shell double-cliquable en l'enregistrant en tant que fichier '.command'. Tout script shell standard peut être sauvegardé dans un fichier avec l'extension '.command', et un double-clic entraînera l'ouverture d'un nouveau terminal et le lancement du script. On peut aussi utiliser l'utilitaire 'open' pour lancer le script à partir de la ligne de commande (toujours dans une fenêtre de nouveau terminal).
Créez différents ensembles regroupant les réglages d'une fenêtre Terminal (couleurs, taille de fenêtre, ...). Enregistrez une session terminal en utilisant Fichier -> Enregistrer sous... pour créer un fichier '.term'. Un double-clic entraînera l'ouverture d'une fenêtre Terminal avec exactement les mêmes réglages que ceux de la fenêtre à partir de laquelle le fichier ".term" a été créé. Placez le fichier dans le dossier ~/Library/Application Support/Terminal/ et il apparaîtra dans le menu Fichier du Terminal sous 'Fichier -> Bibliothèque -> ...' Examinez un fichier '.term' et vous verrez : Ajoutez des commandes shell à cela : et vous obtiendrez un effet similaire à celui du fichier '.command' (voir Mercredi), mais avec en plus la possibilité de modifier les réglages de la fenêtre Terminal. Retirez ';exit' si vous souhaitez pas que la fenêtre se ferme avec exécution complète de Execution String.
Déposer un dossier ou un fichier sur la fenêtre Terminal et le chemin d'accès complet sera inscrit sur la ligne de commande. Le titre du Terminal peut être changé avec : Les exemples ci-dessus affiche le nom de l'utilisateur et celui de l'hôte en utilisant soit echo soit printf.
Cette semaine, je vais vous lister des commandes très utiles dont vous ne connaissez pas l'existence (ou que vous aviez peut-être oubliées). Reportez-vous au manuel Unix pour de plus amples détails. Pour obtenir des informations sur le système :
Si vous souhaitez manipuler des fichiers zippés, utilisez la famille de commandes z*. Par exemple, utilisez 'zmore' pour voir un fichier au lieu de le dézipper, et ainsi en voir le contenu décompressé. Si les fichiers sont compressés avec bzip2, utilisez la famille de commandes bz* :
Utilisez directement (sans passer par osascript) la commande 'say' pour ajouter de la parole à vos scripts : Recherchez des mots à prononcer avec 'look' : Ou scruttez le dictionnaire avec grep : Ou le dictionnaire en ligne pour la signification de 'fuci':
Effectuez une mise à jour de logiciel, éventuellement en ligne, avec l'outil à ligne de commande Software Update : N'oubliez pas 'nvram' pour manipuler les paramètres de l'open firmware : Pour lister les variables nvram : Pour activer la connexion verbeuse (équivalent à Command-V au démarrage) : Utilisez 'bless' pour changer le volume de démarrage :
Utilisez le Scriptable Image Processing System (commande sips) pour manipuler des images via la ligne de commande ou AppleScript. Il n'y a pas de page de manuel (man), utilisez donc :
Les astuces de cette semaine vous aideront à saisir des commandes Bash plus rapidement et plus facilement. Tout d'abord, l'édition de la ligne de commande : Ces commandes seront familières aux utilisateurs d'Emacs. Pour utiliser le mode d'édition de 'vi', tapez la commande : et pour revenir au mode 'Emacs' :
Trouvez rapidement une ligne de commande que vous avez tapée précédemment puis répétez la ou modifiez la. Tapez control-r puis commencez à taper la commande : Commencez par taper une quelconque partie de la ligne de commande, par exemple la commande ou le nom du fichier, et bash recherchera dans son historique la première commande correspondant à ce que vous avez tapé n'importe où sur la ligne. Continuez de taper jusqu'à ce que la commande correcte soit montrée, ou pressez control-r encore pour remonter encore dans l'historique. Lorsque la commande souhaitée est affichée pressez retour pour l'exécuter ou pressez la flèche droite pour l'éditer.
Répétez une suite de commandes :
La séquence escape-. rappelle le nom de fichier de la commande précédente. Tapez : puis : sera changée en - particulièrement utile pour des noms de fichiers longs ou compliqués. En plus, la variable shell $_ peut être utilisée :
Vous savez probablement que le fait de presser la touche Tabulation permet de compléter le nom d'un fichier. Vous pouvez aussi utiliser Tabulation pour compléter des commandes, des alias et des fonctions. Si le mot commence par $, alors une pression sur la touche Tab complètera le mot en se basant sur les variables shell définies. De la même manière, ~ (tilde) sera complété en se basant sur les noms d'utilisateurs et @ en se basant sur des noms d'hôtes. Pour que @ fonctionne, la variable HOSTFILE doit porter le nom d'un fichier contenant des entrées au même format que le fichier /etc/hosts. (Voir 'man hosts')
Vous pouvz faire en sorte qu'une des lignes particulières ne soient pas mémorisées dans l'historique, ceci est pratique si la commande contient des informations sensibles tels qu'un mot de passe. Il y a deux techniques : Positionner la variable d'environnement HISTCONTROL: Maintenant, les commandes commençant avec un espace ne seront pas mémorisées dans l'historique. De plus, les lignes correspondant à la dernière ligne de l'historique ne seront pas ajoutées. Pour contrôler ces aspects individuellement, utilisez 'ignorespace' ou 'ignoredups' au lieu de 'ignoreboth'. La seconde technique consiste à positionner la variable d'environnement HISTIGNORE à une liste de modèles séparés par des point-virgules. Pour plus de détails, se reporter à 'man bash' et rechercher le terme HISTIGNORE.
Utilisez le système d'aide de Bash pour obtenir des informations sur les commandes pré-enregistrées. (Vous ne les verrez pas dans les pages 'man' d'Unix) pour les llister toute. pour afficher la page d'aide d'une commande donnée. Fournissez un modèle et Bash affichera une page d'aide pour chaque commande correspondant au modèle ou un petit synopsis si l'option est -s est donnée.
Lorsque vous tapez une commande telle que 'ls', Bash peut être amené à exécuter un alias, une fonction, une commande interne ou une provenant du chemin d'accès ($PATH). Déterminez le type de commande que Bash exécutera en utilisant la commande 'type'. Elle est analogue à la commande 'which' du shell tcsh. Visualisez toutes les possibilités avec :
L'astuce de Mardi vous a montré comment déterminer la variante d'une commande que Bash va exécuter. Et si vouliez maintenant surpasser cela ? L'ordre de recherche de Bash est le suivant : Utilisez la commande interne suivante de Bash pour changer l'ordre de recherche (changement applicable qu'à une seule commande) : Par exemple : force l'exécution de 'ls' à partir de $PATH, évitant ainsi les alias ou fonctions que vous auriez pu définir pour 'ls'. Note : le shell 'tcsh' utilise un backslash ('\') pour éviter les alias et les commandes internes.
Listez tous les alias avec : Créez un alias avec : Supprimez un alias avec : Voici un truc pour faire des alias à partir de noms de répertoire. Normallement, Bash effectue une substitution d'alias seulement sur le premier mot d'une ligne de commande (la commande seulement) ... ...ainsi cela ne marche pas. Mais faites un alias de cd comme ci-dessous (notez le blanc à la fin)... ... et cela marche maintenant.
Sous Bash, à l'inverse du shell tcsh, les alias ne peuvent pas prendre de paramètres. Bash est caractérisé par la plus puissante construction de 'fonctions'. Déclarez une function 'psx' : La variable spéciale $* est étendue à tous les paramètres passés à la fonction. Autrement, utilisez $1, $2, ... pour le premier et second (et ainsi de suite) paramètres. C'est exactement le même schéma que celui utilisé pour étendre les paramètres passés aux scripts shell. Voici une fonction pour voir les fichiers log : Et : verra le log système (contrôle-C pour sortir). Pour lister toutes les fonctions : ou pour ne lister que les noms de fonction.
Apprenez la différence entre lancer un shell et 'sourcer' un shell. Illustration : Lancez le script : Remarquez que les variables n'ont pas changé... 'Sourcez' le script: ...et cette fois ci elles ont changé. Le lancement d'un script comme dans le premier exemple lance un nouveau shell. Lorsque le nouveau shell se termine, ses variables d'environnement ne sont pas passées au shell parent, elles sont donc perdues et celles du shell original restent inchangées. Le fait de faire un 'sourcing' d'un script l'exécute dans le shell courant. Les variables d'environnement/shell réglées par le script sont celles du shell courant et restent donc positionnées après que le script se soit terminé. Remarquez que : et sont équivalents.
Utilisez des parenthèses pour exécuter des commandes dans un sous-shell. Vous devez vous attendre à ce que ce script vous renvoie Parce que la seconde assignation est entre parenthèses elle est exécutée dans un sous-shell et (rappelez vous de l'astuce de Lundi) elle n'a aucun effet sur l'environnement du shell parent. Vous souhaiterez exécuter de nombreuses commandes dans un sous-shell lorsque leur sortie est redirigée ou envoyée à une autre commande (pipe). En guise d'illustration :
Utilisez les accolades pour exécuter un sous-shell. L'astuce de Mardi a exécuté une liste de commandes placées entre parenthèses : Vous pouvez obtenir le même effet avec des accolades : sauf que la liste de commandes est exécutée dans le shell courant, pas dans un sous-shell. (Comme la différence entre lancer ou sourcer comme expliqué dans l'astuce de Lundi) Notez l'espace après l'accolade ouvrante et le point-virgule avant l'accolade fermante. Ces contraintes de syntaxe sont plus strictes pour les accolades que pour les parenthèses.
Utilisez 'eval' pour supasser l'ordre d'analyse des commandes du shell. Eval est une commande subtile et utile. Considérez ce script qui lance des commandes en arrière-plan. Le script échoue parce que le shell considère que le premier mot ("$*") est une commande *puis* développe $*. Nous devons changer l'ordre d'évaluation du shell. Le fait d'enlever les apostrophes autour de "$*" ne marchera pas non plus : Voilà la solution : Mais la seconde commande échoue toujours. Encore une fois, le shell gère les symboles avant de les développer et n'arrive pas à reconnaître que le '|' est un symbole, le symbole du pipe. Maintenant, essayez avec 'eval' : Ça marche. Pourquoi ? Le shell développe "$*" comme d'habitude. Ce que eval fait consiste à évaluer la ligne de commande, donnant au shell une seconde chance de considérer que '|' est le symbole du pipe.
Commencez une liste de commandes sous-shell, ou un script, en utilisant 'nohup' si vous souhaitez qu'il reste actif après que le shell ait fini de lancer les commandes. Normalement, le shell envoie un signal HUP à tous ses sous-process lorsqu'il reçoit lui aussi un HUP ou une commande 'exit'. 'Nohup' empêche cela. Autrement, construisez un gestionnaire de signaux dans le script pour capturer le signal HUP et l'ignorer. Note :
Vérifiez le avec : (HUP est désactivé en sortie) Activez le avec : Pour désactiver de nouveau : 'Huponexit' s'applique à tous les sous-process, alors que la commande 'nohup' est appliquée sur un process donné.
Utilisez NetInfo pour changer votre shell par défaut. Si votre utilisateur a été créé avant Panther, vous devez peut-être encore utiliser tcsh au lieu de bash. La manière graphique : Lancez le Gestionnaire NetInfo dans /Applications/Utilities et allez à : | / | users | your-user-name | dans les panneaux du haut. Cliquez sur votre nom d'utilisateur. Ensuite, dans le panneau du bas, faites défiler jusqu'en bas jusqu'à ce que vous voyez 'shell' dans le panneau 'Property'. Changez la valeur dans le panneau 'Value(s)' en '/bin/bash'. Vous devrez vous authentifier d'abord en cliquant sur le cadenas placé en bas à gauche et en saisissant votre mot de passe administrateur. La manière ligne de commande : Utilisez la ligne de commande des services de répertoire (remplacez 'saruman' par votre propre nom court d'utilisateur).
Restaurer le Statut de l'utilisateur Admin. Si votre utilisateur admin a perdu son statut d'administrateur pour une quelconque raison (et c'est arrivé à pas mal de gens) et que vous n'avez pas de deuxième utilisateur adminsitrateur, vous devez démarrer en mode utilisateur unique et utilisez 'nicl' pour vous ajouter de nouveau au groupe administrateur. Maintenez pressées les touches commande et 's' au démarrage et attendez que le texte s'arrête de défiler. Tapez la commande : pour monter le disque système avec des autorisations en écriture (il sera déjà monté mais en lecture seule). Restaurer le statut de l'administrateur en utilisant 'nicl'. Vous ne pouvez utililser aucun autre utilitaire tel que 'niload' car le démon nécessaire des services système ne tourne pas. (Tout sur une même ligne.)
Gérez la base de données NetInfo. Questionner la base de données Netinfo pour voir quels utilisateurs utilisent le shell 'sh' oo 'bash'. Avec nigrep : nigrep prend comme argument une expression régulière comme grep et cherche dans la base de données. Avec nireport : nireport prend comme argument un répertoire (/users dans cet exemple) et une liste de propriétés à afficher. Listez les répertoires NetInfo avec nidump. nidump affiche les répertoires NetInfo au format Unix standard : Chargez des données dans NetInfo avec niload. niload chargera la base à partir de fichiers plats standard Unix : Consultez 'man niload' pour voir si vous avez besoin des options 'd'elete ou 'm'erge. Gérez la base de données avec niutil or nicl. Je préfère utiliserto 'dscl' pour cela, et j'en parlerai dans les astuces de la semaine prochaine.
La base de données NetInfo est sauvegardée quotidiennement avec : /private/var/backups/local.nidump Vous pouvez faire cela vous-même avec : Restaurez une base de données corrompues avec : Démarrez en mode mono-utilisateur (maintenez Commande-s au démarrage et attendez que le texte finisse de défiler). Tapez les commandes : Les prochaines étapes ont été tirées d'un article publié chez O'Reilly. Elles lancent NetInfo et créent une base de données vide. Enfin, utilisez niload pour charger la base de données sauvegardées :
Sous Panther, la plupart des fichiers Unix sont scrutés, comme NetInfo et les Services de Répertoire. Vérifiez l'ordre de recherche des services avec : Changez cela pour tout service en créant un fichier dans le répertoire '/etc/lookupd/'. Par exemple, pour contrôler comment sont recherchés les mounts NFS (par défaut NetInfo mais pas le /etc/fstab 'fichier plat') créez un fichier appelé mounts: Cela indique de scruter les fichiers plats, puis NetInfo et enfin les Directory Services.
Les astuces de cette semaine abordent les signaux Unix et la manière de les gérer dans des scripts shell Bash. Aujourd'hui, je vous parlerai des signaux et des interruptions. Envoyez un signal à un process actif en utilisant 'ps' et 'kill' avec une simple fonction bash. Fonction : Usage : Listez quelques uns des signaux les plus communs : Rappelez vous que certains signaux sont associés à des touches : Listez les associations avec stty : Changez les associations (associez une interruption à control-x au lieu de contrôle-c) :
Un signal est une interruption envoyée à un process Unix actif. Normalement, le signal provoque la fin du process (script ou exécutable). Cependant, un process peut capturer le signal et effectuer une autre action. Capturez les signaux dans des scripts bash : Si le script reçoit un signal INT ou TERM via 'kill', ou un signal INT via contrôle-c, il exécutera la commande donnée par la trappes appropriée puis il continuera là où il s'est arrêté. Dans cet exemple, il affichera un message à l'écran. Lancez trap1 : Dans une autre fenêtre (en utilisant la fonction killsig de Lundi) : Syntaxe :
Utilisez une fonction si vous avez besoin d'un gestionnaire de trappes plus sophistiqué : Si un signal HUP est envoyé à ce script, il sera attrapé par 'trap' et la fonction 'handlehup' sera exécutée. Lorsque la fonction sera terminée, le script continuera son exécution au point où il s'était arrêté. Dans une autre fenêtre (en utilisant la fonction de l'astuce de Lundi) : Le signal HUP signal (hangup) est généralement utilisé pour indiquer au process de recharger configuration et de redémarrer. Apache répondar à un signal HUP de cette manière (bien que l'on utilise 'apachectl' en général).
Limitez vos fonctions trappes qu'à la partie critique d'un script, souvent autour d'un nombre de commandes ne devant pas être interrompues. Ce script attrape les signaux HUP, INT et TERM autour du code critique puis pousse le gestionnaire vers le code normal. L'instruction : retire un gestionnaire des signaux listés et le remplace par celui par défaut (s'il y en a un). Dans une autre fenêtre (en utilisant la fonction killsig de Lundi) :
Limitez vos fonctions trappes à seulement la partie critique d'un script, comme Jeudi, mais en utilisant des sous-shells. Un gestionnaire assigné à un sous-shell n'hérite pas du shell parent. Ce script attrape les signaux INT (control-c) autour du code critique. Listez tous les signaux avec : Et obtenez en plus sur la commande 'trap' intégrée au bash avec :
Servez vous des Tâches en Arrière Plan pour les traitements qui durent très longtemps et qui ne nécessitent aucune entrée/sortie via le Terminal, ou qui lancent leur propre fenêtre (xterm par exemple). Ces astuces s'appliquent au shell bash mais tcsh supporte aussi les Tâches en Arrière Plan. Lancez une nouvelle fenêtre xterm avec : et une fois que xterm sera lancé vous aurez de nouveau le contrôle du terminal original. Le symbole '&' indique à bash de lancer la commande en arrière plan. Utilisez : pour afficher une liste des tâches ainsi que leur numéro de process et leur PID. Notez que chaque instance de bash (chaque fenêtre terminal) lance et contrôle sa propre liste de tâches. Le fait de taper 'jobs -l' sur un autre terminal ne montrera pas la tâche qui porte le PID 707.
En général, les scripts qui requièrent des entrées/sorties ne sont pas lancés en arrière-plan. La sortie serait mélangée à celle de la tâche de premier plan et les entrées ne marcheraient pas. Utilisez une redirection de fichier si une tâche en arrière-plan affiche des données ou requiert des entrées prévisibles : Quand la tâche se termine le terminal affiche : Et pour prouver qu'il a marché :
Reprennez la main via le terminal sur une tâche que vous avez placée en arrière-plan. Pressez contrôle-z pour suspendre la tâche, puis tapez 'bg' pour la place en arrière-plan. La tâche va alors continer de s'exécuter comme si vous l'aviez lancée en arrière-plan en utilisant '&'.
Utilisez 'fg' et 'bg' pour gérer les tâches en arrière-plan. place la tâche numéro n en premier-plan. 'fg' sans paramètre opère sur la tâche la plus récemment mise en arrière-plan. Vous pouvez aussi spécifier le numéro PID avec 'fg' en omettant le %. Fournissez une entrée à une tâche placée en arrière-plan (cette exemple utilise le script de Mardi) : Ici, le Terminal indique que la tâche 2 a été stoppée. Utilisez 'jobs -l' pour en connaître la cause... ...elle nécessite une entrée à partir du terminal '(tty input'). Placez la tâche en premier-plan : Fournissez maintenant l'entrée : enverra la tâche de nouveau en arrière-plan si elle a besoin de continuer son exécution. 'bg' peut prendre comme argument %numéro-de-tâche ou le PID comme pour 'fg'. Sans paramètre, elle se base sur la tâche dernièrement placée en premier-plan.
Si un shell (ou un script) s'arrête alors que des tâches en arrière-plan qu'il contrôle sont toujours actives, ces tâches deviennet orphelines. Elles ne peuvent être arrêtées qu'avec : Eviter qu'un script crée des tâches orphelines en utilisant 'wait'. évitera que le shell (et donc le script) s'arrête tant que les tâches qu'il a sous contrôle ne sont pas terminées. attend seulement la tâche numéro n. Vous pouvez spécifier aussi un PID sans le '%'.
Utilisez : ou : pour savoir quelles conditions on peut utiliser sous les scripts des shells Bash et Bourne pour les instructions 'if', 'while' et 'until'. Les conditions sous Bash sont évaluées par la commande 'test', qui peut tester des fichiers, des chaînes et des nombres. La commande est aussi appelée '[' qui explique la forme d'une condition Bash. Une forme équivalente : Pourquoi ";" doit être placé avant 'then' ?
Utilisez plus les conditions Bash - comprenez qu'une condition est réellement une commande. Bash exécutera la 'condition' et testera la valeur retournée. Ceci est en rapport avec les explications de Lundi concernant les commandes 'test' et '['. Par exemple : La valeur de retour d'une commande est tenue dans une variable shell $?
Utilisez les constructions AND et OR pour bâtir des conditions plus complexes. L'instruction de test utilise les opérateurs -a pour AND et -o pour OR. Autrement, utilisez les opérateurs AND et OR de Bash : La différence entre les deux : Dans le premier exemple, la commande 'test' '[ ... ]' évalue l'expression entière. Dans le second exemple, 'test' est appelée deux fois et Bash évalue 'premier résultat de test' AND 'second résultat de test'.
Utilisez les tests intégrés de Bash pour l'arithmétique des entiers (et seulement les entiers). L'utilisation de '<' au lieu de '-lt' rendent les tests plus lisibles. L'expression est entourée par (( ... )) au lieu de [ ... ]. ou : Comprenez la différence entre les deux formes.
Comprenez comment formuler des expressions complexes. Quelques fois, les expressions doivent être placées entre crochets pour forcer l'ordre correct de l'évaluation. (Bien que dans l'exemple qui suit les crochets ne sont pas strictement nécessaires) Erreur de syntaxe, nous devons échapper l'expression entre crochets. Essayez : 3 < 2 < 1 ! You jest. Essayez maintenant : C'est nettement mieux. Essayez de voir pourquoi nous avons obtenu une erreur dans la seconde forme.
Connaître les caractères spéciaux. Bash traite de manière spéciale de nombreux caractères. Si l'un de ces caractères apparaît nu (sans guillemet ou sans caractère d'échappement) sur la ligne de commande, il est remplacé ou interprété. Voici un rappel pratique. D'autres...?
Empêcher Bash d'interpréter des caractères spéciaux (voir Lundi). Il y a trois méthodes: 1) Echappement avec Backslash Aucun des $, * ou > n'a été interprété de manière spéciale. 2) Guillemets (citation forte) Tout ce qui est dans '...' est traité de manière litérale : le shell n'interprète aucun caractère spécial. 3) Apostrophes (citation légère) Tout sauf $ et ce qui est dans "..." est traité de manière litérale : cela vous permet d'échapper des caractères spéciaux tout en développant des variables. Si vous souhaitez mixer des litéraux $ et des développements de variables $, utilisez le backslash pour échapper le $ :
1) Paramètres Il est parfois nécessaire d'utiliser des guillemets autour de paramètres comme dans l'exemple Awk suivant : Si j'avais voulu afficher "can't" au lieu de "cant", une première tentative aurait pu être : Il n'est pas possible d'échapper le ' dans can't car il est placé à l'intérieur d'une chaîne '...'. Utilisez : Cela coupe le paramètre Awk en 3 chaînes adjacentes : 2) Rappelez vous que les guillemets n'ont rien de spécial quand elles sont à l'intérieur d'apostrophes, vous pouvez donc utiliser aussi : ou même : car $ sans rien derrière est considéré comme le litéral $.
Comprenez l'ordre d'évaluation adopté par le shell. Cela ne marche pas : Le tilde (~) est un caractère spécial du shell et n'a aucun sens dans le système de fichier. Le fait de le placer entre guillemets évite que le shell ne le développe. Vous devez penser qu'il est développé dans l'expression : mais cela n'est pas le cas. Le shell développe '~' avant qu'il ne développe $variables, et il ne voit donc jamais le '~'. Contournez le problème : 1) Utilisez eval eval donne au shell une seconde chance pour développer. Le premier passage développe $file, puis le tilde est développé par 'eval'. 2) Ne mettez pas de guillemets La première ligne n'a pas de guillemet, file contient donc le chemin d'accès complet au lieu de '~/Desktop' Si vous devez mettre des guillemets dans l'assignation de la variable file, utilisez $HOME. $HOME est développée dans l'assignation alors que ~ ne l'est pas.
Comptez le nombre de fois que le shell évalue une expression. Voici un exemple simple qui illustre le principe. Le script ne marche pas parce que le shell a traité l'espace échappé par le backslash au moment d'exécuter l'echo. Le fichier ne contient donc pas la séquence d'échappement : On doit échapper à la séquence d'échappement en écrivant escape-space dans le fichier. Les deux doivent être échappés par eux mêmes - nous devons écrire escape-escape escape-space :
Monter un partage AFP en utilisant le Terminal. Un partage AFP peut être monté n'importe où sur le système de fichiers?par exemple dans /Volumes ou à la racine de votre répertoire Départ. Le 'point de montage' doit être un répertoire existant. Par exemple, pour monter mon répertoire départ à partir d'une autre machine (melkor) sur le point de montage 'melkor' situé dans mon répertoire départ de cette machine, j'utilise : '@melkor.mayo-family.com/myuser' est le nom d'hôte ou l'adresse IP du serveur suivi par le point de partage AFP comme ce que l'on voit dans le dialogue 'Se connecter à...' du Finder. Pour démonter, utilisez : et le répertoire sera supprimé.
Ces script est utile si vous avez des comptes sur plusieurs machines (de bureau ou portables). Il monte votre répertoire Départ d'une autre machine. L'utilisation la plus simple est : Il suppose ce qui suit. Votre nom d'utilisateur est le même sur les deux machines, si ce n'est pas le cas remplacez le avec l'option '-u autrenom'. Le nom du serveur est défini dans la variable d'environnement $ALM_SERVER, sinon remplacez le avec l'option '-h hostname/ip-address'. Le point de montage sera $ALM_AFP_MOUNT/hostname/username, où $ALM_AFP_MOUNT est une variable d'environnement. Le chemin d'accès dans $ALM_AFP_MOUNT doit exister. /Volumes est le chemin d'accès usuel, mais vous pouvez le changer pour éviter des confusions avec les partages montés par le Finder (en /nfs par ex). Le script créera tous les répertoires si nécessaire.
La façon la plus simple d'activer NFS sur OS X est d'utiliser NFS Manager. Ce produit est brièvement décrit dans les astuces OSX (en anglais). NFS Manager écrit les Partages et les Connexions (Montages) dans NetInfo. L'astuce vous montre comment autoriser NFS à fonctionner à partir des fichiers plats Unix traditionnels. /etc/fstab définit quels partages à monter automatiquement (nécessaire sur la machine client) /etc/exports définit quels répertoires à partager (nécessaire sur le serveur) D'abord, forcez le démon automount à lire les fichiers plats. Par défaut, il utilisera NetInfo (Panther et Jaguar). Créez le répertoire /etc/lookupd et le fichier mounts comme suit. Sur Jaguar (mais pas Panther) il est nécessaire de forcer le démon RPC à démarrer en s'assurant que RPCSERVER est positionné sur -YES- dans /etc/hostconfig: Ensuite, redémarrez la machine et réglez les partages (serveur) et les montages (client) ... astuce de Jeudi.
Pour définir des points de partage sur le serveur, éditez /etc/exports. Dans cet exemple, le répertoire /Users est exporté. '-alldirs' permet à tout sous-répertoire de /Users d'être monté par un client '-maproot=nobody' s'assure que l'utilisateur root sur le client n'a pas des accès root sur le serveur ; ESSENTIEL, à moins que vous sachiez exactement ce que vous faites '-network...' et '-mask...' définissent la tranche d'IP autorisées à monter le partage. Il est ESSENTIEL que cette tranche ne comprenne que des machines de confiance (voir note plus bas). J'ai exporté /Users/Shared en tant que lecture seule (-ro). Ceci est accessible à TOUTES les machines (aucune restriction IP). Il est exporté en Lecture Seule et tous les utilisateurs sont aiguillés vers l'utilisateur sans privilège 'nobody'. Voir 'man exports' pour plus de détails. Pour définir des points de montage sur le client : Cette ligne recherche le partage /Users sur l'hôte carcharoth (vous pouvez utiliser soit le nom d'hôte, soit l'adresse IP) et monte le répertoire /nfs/Carcharoth. '/nfs' doit exister mais le point de montage réel 'Carcharoth' sera créé automatiquement. 'nfs' indique que le partage est nfs Les options -b,-i -P sont décrites dans 'man mount_nfs'. Les deux derniers ( 0 0 ) indique la 'dump frequency' et l'ordre de vérification du système de fichier. Ils ne sont pas utilisés. Note : NFS n'utilise aucun mot de passe pour l'authentificationn mais plutôt les ID Unix du User et du Group. Il est supposé qu'ils soient cohérents sur le serveur et sur tous les clients. En fait, un compte utilisateur sur la machine client aura les mêmes ID de user et de group que ceux de son compte sur le serveur (et tous les autres clients). Ceci est vrai en général sur un réseau client-serveur propre où les données utilisateurs sont gérées sur le serveur. Si une machine client se connecte à votre serveur, elle doit seulement avoir un utilisateur ayant le même ID de User et de Group qu'un utilisateur du serveur pour avoir un accès total aux fichiers de cet utilisateur sur le serveur.
Taper un mot de passe sur une ligne de commande peut poser un risque de sécurité compte tenu que le mot de passe sera sauvegardé dans l'historique des commandes de Bash, et pire, écrit dans le fichier historique. Ajoutez cette ligne dans votre fichier de démarrage bash (/etc/profile, /etc/bashrc, ~/.bash_profile, ou ~/.bashrc) : Une ligne de commande commençant par un espace ne sera pas ajoutée à l'historique. Ainsi, commencez toute commande comprenant un mot de passe par un espace en guise de précaution.
Les astuces de cette semaine porteront sur sed, un utilitaire pratique permettant d'exécuter un script de commandes d'édition sur ses entrées. Supprimer les lignes vides d'un fichier. Utilisez : sed fonctionne en appliquant une expression régulière délimitée à chaque ligne d'entrée (^$ dans cet exemple). Si la ligne correspond alors sed applique les commandes d'édition qui suivent. 'd' supprime la ligne. Voir les astuces des semaines 59 et 60 pour plus d'informations sur les expressions régulières. Pour écrire le résultat dans le fichier d'origine, utilisez ce truc : Supprimez les lignes contenant un texte spécifique. Utilisez la même technique avec une expression régulière appropriée. Cet exemple supprime toutes les lignes commençant par '$'.
Utilisez sed pour rechercher et afficher des lignes particulières, dans le style de grep. En mode normal, sed renvoie les lignes d'entrée vers sa sortie. L'option '-n' annule ce comportement. La commande d'édition 'p' affiche chaque ligne qui correspond. La combinaison des deux indique à sed de n'afficher que les lignes correspondantes. Vous pouvez souhaiter éditer le contenu du fichier et n'afficher que les lignes modifiées :
Modifiez une rangée de lignes avec sed. Les exemples précédents ont utilisé une expression régulière pour trouver les lignes à modifier. sed peut aussi opérer sur une rangée de lignes ou sur une seule ligne. Supprimez toutes les lignes entre le marqueur de début et le marqueur de fin inclus. Ou afficher les : Ou modifier les : Si vous pensez que le terme 'don' puisse apparaître plus d'une fois sur une ligne, utilisez l'option 'g' (global) pour remplacer toutes les occurences d'une ligne.
Appliquez une commande d'édition plusieurs fois sur une ligne. Spécifiez des commandes multiples à sed en utilisant une de ces deux techniques. Option -e: Séparez plusieurs commandes avec ';' :
Utilisez un fichier script si le script sed devient trop long ou trop complexe. Ecrivez le script dans un fichier texte normal en plaçant chaque commande sur une ligne à part. Utilisez l'option '-f' pour spécifier un fichier script.
Les astuces de cette semaine explorent Awk, un utilitaire pratique qui exécute un script de commandes d'édition passé en entrée. Reportez vous aussi aux astuces de la semaine précédente sur Sed qui présente des fonctions similaires. Imprimer des lignes contenant un texte spécifique. Cet exemple imprime toutes les lignes commençant par '$'. Supprimer les lignes blanches d'un fichier. Pour enregistrer le résultat dans le fichier d'origine, utilisez cette astuce : Awk fonctionne en faisant correspondre chaque ligne passée en entrée à un modèle (dans ces exemples, une expression régulière '^$' pour les lignes commençant par '$', et '.+' pour les lignes contenant au moins un caractère). Si les lignes passées en entrée correspondent alors Awk applique les actions qui suivent et qui sont placées dans {...}. 'print($0)' imprime la ligne entière, comme le fait un simple 'print'. Si aucun modèle n'est passé alors toutes les lignes correspondent. Si aucune action n'est donnée alors la ligne est imprimée. L'exemple du dessus peut être simplifié comme suit : Notez que la différence entre imprimer et supprimer est une expression régulière inversée. Voir les astuces des semaines 59 et 60 pour plus d'informations sur les expressions régulières.
Affichez des champs spécifiques de chaque ligne correspondant aux critères. L'astuce de Lundi utilisait l'action {print($0)}. $0 représente la ligne entière passée en entrée. $n représente le champ n. Les champs sont séparés par des espaces. Une application commune revient à afficher des informations spécifiques provenant de la sortie de commandes Unix telles que la et ps. Affichez juste le numéro pid (champ 1) : Affichez le mois, la date et le nom de fichier à partir d'un long listing : Utilisez printf pour formatter la sortie : La première ligne 'Date: , File' résulte de la première ligne affichée par ls -l. Cela peut être facilement retiré avec sed, grep ou awk. Pour en savoir plus sur printf, se reporter à :
Traitez une rangée de lignes avec Awk. Les exemples précédents ont utilisé une expression régulière pour filtrer les lignes. Awk peut être appelé pour traiter une rangée de lignes ou une seule ligne. Affichez toutes les lignes entre begin-marker et end-marker compris. Ou simplement :
Executez plusieurs commandes pour chaque ligne en entrée. Séparatez les commandes avec ';' et toutes les commandes seront exécutées pour chaque ligne répondant aux critères. Pour afficher la longueur de chaque ligne et la ligne elle-même, utilisez : Cela pourrait être effectué avec une seule instruction print mais cela illustre l'utilisation de commandes multiples. En développant l'astuce de Mercredi, nous pouvons afficher des lignes qui sont en dehors d'une rangée spécifique : Les lignes correspondant aux critères exécutent 'next', ce qui saute la ligne. Les lignes ne correspondant pas ne l'exécutent pas, donc 'print' est exécutée. Notez que c'est différent du premièr exemple où deux commandes étaient appliquées au même modèle de recherche : Ici, nous appliquons la première commande au premier modèle et la seconde commande aux deuxième modèle (qui est vide pour s'appliquer à toutes les lignes). Cela ne marche pas :
Specifiez plusieurs modèles à appliquer à chaque ligne répondant aux critères : Appliquer une commande différente à chaque modèle : Appliquer une commande aux lignes qui correspondent à un modèle ou à un autre en utilisant l'opérateur 'or' (||) : Appliquer une commande aux lignes qui correspondent aux deux modèles en utilisant l'opérateur 'and' (&&) :
Voir la semaine 86 pour une introduction à AWK. Changez le séparateur de champ par défaut utilisé par Awk. Les fichiers à valeurs séparées par des virgules ('Comma Separated Value') représentent un moyen populaire d'exporter des tables de données (les tableurs peuvent exporter au format CSV). Par exemple : Awk utilisera normalement des espaces comme séparateur de champ. Pour changer cela, utilisez l'option -F : Autrement, nous pouvons changer la variable Awk 'FS' en utlisant BEGIN. Les commandes dans {...} qui suivent BEGIN sont exécutées avant que le script Awk ne démarre. Le séparateur de champ est en fait une expression régulière et peut accepter une liste de séparateurs ou des jokers classiques d'expressions.
Test
Salut à tous.
Ce texte est le résultat
d'un "Document Céans"
Fin
$
#!/bin/bash
today=$(date)
cat <
Salut à tous. Nous sommes le $today.
EOD
$ ./hd
Salut à tous. Nous sommes le Mon Feb 16 11:53:46 GMT 2004.
$
#!/bin/bash
today=$(date)
cat <<'EOD'
Salut à tous. Nous sommes le $today.
EOD
$ ./hd
Salut à tous. Nous sommes le $today.
$
$ cat hd
#!/bin/bash
if [ "$1" = "" ]; then
cat <<-EOD
Hello there.
Today is $(date).
EOD
fi
$ ./hd
Hello there.
Today is Mon Feb 16 12:08:16 GMT 2004.
$
#!/bin/bash
read_data ()
{
read make
read model
read colour
}
read_data <
BMW
3 series
Blue
HEREDOC
echo "Make: $make, model: $model, colour: $colour"
$ ./hd
Make: BMW, model: 3 series, colour: Blue
$
Commentaires / Variables de Test
$ cat hd
#!/bin/bash
echo "avant"
:<<'EOD'
if [ "$1" = "" ]; then
echo "Aucun paramètre passé"
fi
EOD
echo "après"
$ ./hd
avant
après
$
#!/bin/bash
var1=hello
: <
${var1?} ${var2?}
ERRORIFNOTSET
$ ./hd
./hd: var2: paramètre nul ou non positionné
$
$ mv *.html *.php
usage: mv [-fi] source target
mv [-fi] source ... directory
#!/bin/bash
shopt -s nullglob
for file in *.$2; do
$1 "$file" "${file%.$2}.$3"
done
$ cat ext
#!/bin/bash
if [ "$3" = "" ] || [ "$4" != "" ]; then
echo 'For each file *.ext1, executes "command file.ext1 file.ext2"'
echo ' eg "cp html php" pour copier tous les fichiers html en équivallents php'
echo ' "mv html php" pour renommer tous les fichiers html et leur attribuer une extension php'
echo "Usage: ${0##*/} command ext1 ext2"
exit
fi
# cette option permet de retourner null et non *.$2 si aucun fichier ne correspond à *.$2
shopt -s nullglob
for file in *.$2; do
$1 "$file" "${file%.$2}.$3"
done
Traitement Récursif des Extensions
$ cat rext
#!/bin/bash
for dir in $(find . -type d); do
pushd $dir > /dev/null
ext $1 $2 $3
popd > /dev/null
done
$ cat rext
#!/bin/bash
if [ "$3" = "" ] || [ "$4" != "" ]; then
echo 'Exécute "command file.ext1 file.ext2" sur les fichiers trouvés '
echo ' dans la hiérarchie du répertoire'
echo ' eg "cp html php" pour copier tous les fichiers html en leur équivalents php'
echo ' "mv html php" pour changer tous les fichiers html en fichiers php'
echo "Usage: ${0##*/} command ext1 ext2"
exit
fi
for dir in $(find . -type d); do
pushd $dir > /dev/null
ext $1 $2 $3
popd > /dev/null
done
$ cat each
#!/bin/bash
filetype=$1
shift
for file in $filetype; do
$* "$file"
done
$ cat each
#!/bin/bash
if [ "$2" = "" ]; then
echo "Exécute une commande sur tous les fichiers correspondants"
echo "du répertoire courant"
echo "Usage: ${0##*/} filetype commande-à-exécuter"
exit
fi
filetype=$1
shift
for file in $filetype; do
$* "$file"
done
Traiter Plusieurs Fichiers de Manière Récursive
$cat reach
#!/bin/bash
filetype=$1
shift
find . -name "$filetype" -print0 | xargs -0 -n1 $*
% cat reach
#!/bin/bash
if [ "$2" = "" ]; then
echo "Exécute une commande sur tous les fichiers correspondants"
echo "de la *hiérarchie du répertoire"
echo "Usage: ${0##*/} filetype commande-à-exécuter"
exit
fi
filetype=$1
shift
find . -name "$filetype" -print0 | xargs -0 -n1 $*
$ cat sedx
#!/bin/sh
tmp=tmp-file-for-$PPID
{ sed "$1" "$2" > $tmp
&& mv $tmp "$2"
} || rm $tmp
$ cat sedx
#!/bin/sh
if [ "$2" = "" -o "$1" = "-usage" ]; then
echo "Exécute une commande sed en écrivant dans le fichier d'origine."
echo "Usage: ${0##*/} sed-command file"
echo "Ou utilisez avec (r)each"
echo "Usage: (r)each filetype ${0##*/} sed-command"
exit
fi
tmp=tmp-file-for-$PPID
{ sed "$1" "$2" > $tmp
&& mv $tmp "$2"
} || rm $tmp

Deux utilitaires à ligne de commande sont prodigués pour copier et coller :
$ pbpaste
hello there
(tcsh)
alias precmd 'printf "33]0;$user@$host07"'
$ arch
ppc
$ machine
ppc7450
$ uname -v
Darwin Kernel Version 7.3.0: Fri Mar 5 14:22:55 PST 2004;
root:xnu/xnu-517.3.15.obj~4/RELEASE_PPC
$ hostinfo
Mach kernel version:
Darwin Kernel Version 7.3.0:
Fri Mar 5 14:22:55 PST 2004; root:xnu/xnu-517.3.15.obj~4/RELEASE_PPC
Kernel configured for a single processor only.
1 processor is physically available.
Processor type: ppc7450 (PowerPC 7450)
Processor active: 0
Primary memory available: 768.00 megabytes.
Default processor set: 94 tasks, 249 threads, 1 processors
Load average: 2.37, Mach factor: 0.22
$ system_profiler
(much output)
Manipuler des Fichiers (B)Zippés
$ ls /usr/bin/z*
/usr/bin/zcat /usr/bin/zdiff /usr/bin/zgrep /usr/bin/zmore /usr/bin/zprint
/usr/bin/zcmp /usr/bin/zforce /usr/bin/zip /usr/bin/znew
$ ls /usr/bin/bz*
/usr/bin/bzcat /usr/bin/bzegrep /usr/bin/bzip2 /usr/bin/bzmore
/usr/bin/bzcmp /usr/bin/bzfgrep /usr/bin/bzip2recover
/usr/bin/bzdiff /usr/bin/bzgrep /usr/bin/bzless
zyga
zygadenine
Zygadenus
Zygaena
zygaenid
Zygaenidae
...
dadap
decap
dreep
droop
$ curl dict://dict.org/d:fuci
220 pan.alephnull.com dictd 1.8.0/rf on Linux 2.4.18-14
2. (Bot.) A genus of tough, leathery seaweeds, usually of a
dull brownish green color; rockweed.
Note: Formerly most marine alg? were called fuci.
.
250 ok [d/m/c = 1/0/22; 0.000r 0.000u 0.000s]
221 bye [d/m/c = 0/0/0; 0.000r 0.000u 0.000s]
Software Update Tool
Copyright 2002-2003 Apple Computer, Inc.
Your software is up to date. (Votre logiciel est à jour)
sudo bless -folder '/System/Library/CoreServices' -setOF
Edition de la Ligne de Commande
Editez la ligne courante (ou provenant de l'historique des commandes invoqué en pressant la touche 'flèche vers le haut') avec plus de possibilités que celles offertes par l'habituel curseur et la touche d'effacement (del).
control-E déplace le curseur en fin de ligne
escape-del efface le mot derrière le curseur
del efface le caractère derrière le curseur
control-d efface le caractère après le curseur
esc-d efface le mot après le curseur
control-k efface tout jusqu'à la fin de la ligne
control-u efface toute la ligne
Recherche dans l'Historique des Commandes
(reverse-i-search)`':
type si
(reverse-i-search)`si': vim signal.c
type t
(reverse-i-search)`sit': vim ~/sites/index.html
Pressez la touche Haut jusqu'à ce que la première commande de la séquence à répéter soit affichée. Puis, au lieu de taper retour, tapez control-o. La commande sera exécutée puis la commande suivante sera affichée prête à être exécutée ou modifiée.
osxfaq
Extension de la Ligne de Commande
ls is aliased to `/usr/local/bin/ls --color=tty'
ls is aliased to `/usr/local/bin/ls --color=tty'
ls is /usr/local/bin/ls
ls is /bin/ls
alias, mots clés, fonctions, commandes internes, commandes trouvées par le chemin d'accès $PATH
/Users/saruman
$ alias pref="~/Library/Preferences/"
$ cd pref
-bash: cd: pref: No such file or directory
$ cd pref
$ pwd
/Users/saruman/Library/Preferences
$ psx safari
503 ?? S 12:36.51 /Applications/Safari.app/Contents/MacOS/Safari -psn_0_2359297
Faire des Sous-Shell ou ne pas Faire des Sous-Shell
$ new_var="xxxx"
$ echo $NEW_ENV_VAR
XXXX
$ echo $new_var
xxxx
$ cat tst
#!/bin/bash
declare -x NEW_ENV_VAR="TEST"
new_var="test"
$ echo $NEW_ENV_VAR
XXXX
$ echo $new_var
xxxx
$ echo $NEW_ENV_VAR
TEST
$ echo $new_var
test
new_var="xxxx"
echo $new_var
(new_var="test")
echo $new_var
$ ./tst2
xxxx
xxxx
test
hello
$ cat outfile
world
$ (echo hello; echo world) > outfile
$ cat outfile
hello
world
#!/bin/bash
"$*" > ~/outfile &
$ tst 'du -sk *'
./tst: line 2: du -sk *: command not found
$ tst 'ls | grep "^D"'
./tst: line 2: ls | grep "^D": command not found
#!/bin/bash
$* > ~/outfile &
$ cat ~/outfile
5524 Desktop
1992 Development
...
$ ls: |: No such file or directory
ls: grep: No such file or directory
ls: "^D": No such file or directory
#!/bin/bash
eval "$*" > ~/outfile &
$ tst 'du -sk *'
$ cat ~/outfile
5524 Desktop
1992 Development
...
$ tst 'ls | grep "^D"'
$ cat ~/outfile
Desktop
Development
Documents
En fonction de ses réglages, bash peut envoyer ou ne pas envoyer de signal HUP à ses sous-process.
huponexit off
$ shopt huponexit
huponexit on
$ shopt huponexit
huponexit off
12 /users/root: shell /bin/sh
67 /users/saruman: shell /bin/bash
nobody /usr/bin/false
root /bin/sh
daemon /usr/bin/false
...
saruman /bin/bash
nobody:*:-2:
nogroup:*:-1:
wheel:*:0:root
...
saruman:*:501:
$ mv /var/db/netinfo/local.nidb /var/db/netinfo/corrupt.nidb
$ /usr/sbin/configd
$ /sbin/SystemStarter
$ /usr/libexec/create_nidb
$ /usr/sbin/netinfod -s local
LookupOrder Cache FF NI DS
SUSP - contrôle-z
QUIT - contrôle-q
$ cat trap1
#!/bin/bash
trap 'echo "On no you dont"' INT
trap 'echo "not that way either"' TERM
while true; do
echo "Hello........"
# utiliser sleep pour représenter un long bloc de code
sleep 1
done
Hello........
^XOn no you dont
Hello........
not that way either
Hello........
Hello........
$ killsig TERM trap1
$ killsig KILL trap1
$ cat trap2
#!/bin/bash
handlehup ()
{
echo "J'ai eu un HUP"
echo "Je vais maintenant recharger ma configuration"
#......
}
trap "handlehup" HUP
while true; do
echo "Hello........"
# utiliser sleep pour représenter un long bloc de code
sleep 1
done
Hello........
J'ai eu un HUP
Je vais maintenant recharger ma config
Hello........
^C
$
Poser une Trappe sur une Section de Code
$ cat trap3
#!/bin/bash
handlesig ()
{
echo "Got an INT"
#......
}
# critical code - stop interrupts
trap "handlesig" HUP INT TERM
echo "Critical code"
# use sleep to represent a lengthy block of code
sleep 1; sleep 1; sleep 1; sleep 1; sleep 1; sleep 1
sleep 1; sleep 1; sleep 1; sleep 1; sleep 1; sleep 1
# normal code - allow interrupts
trap - HUP INT TERM
echo "Normal code"
sleep 1000
Critical code
Got an INT
^CGot an INT
Normal code
Hangup
(wait a bit until normal code is entered)
$ killsig HUP trap3
Poser une Trappe sur une Section avec des Sous-Shells
$ cat trap4
#!/bin/bash
# critical code - stop interrupts
(
trap 'echo "Caught by subshell"' INT
echo "Critical code"
sleep 1; sleep 1; sleep 1; sleep 1; sleep 1; sleep 1
sleep 1; sleep 1; sleep 1; sleep 1; sleep 1; sleep 1
)
# normal code - allow interrupts
echo "Normal code"
sleep 1000
$ ./trap4
Critical code
^CCaught by subshell
^CCaught by subshell
^CCaught by subshell
Normal code
^C
$
[1] 707
[1] est le numéro de la tâche
707 est le PID, comme indiqué par 'ps'
$ ps x | grep "[x]term"
707 std S 0:00.16 xterm
[1]+ 707 Running xterm &
#!/bin/bash
read -p "Name: " name
echo Vous déclarez être $name.
...
$ cat in
Adrian
$ ./script
[7] 809
$
[7] Done ./script
Vous déclarez être Adrian.
Mettre en Arrière-plan une Tâche Active
^Z
[7]+ Stopped xterm
$ bg
[7]+ xterm &
$ (contrôle retourné au terminal courant)
$ ./script &
[2] 905
Name: $
[2]+ Stopped ./script
$ jobs -l
[1]- 893 Running xterm &
[2]+ 905 Stopped (tty input) ./script
./script
Vous déclarez être Adrian.
$ bg
$ if [ 3 -lt 7 ]; then
echo "3 est plus petit que 7"
else
echo 'très bizarre !'
fi
3 est plus petit que 7
not 0 (failure) = false
$ if diff f1.txt f2.txt; then
echo "Les fichiers sont identiques"
else
echo "Les fichiers sont différents"
fi
Les fichiers sont identiques
$ echo $?
0
$ a=1;b=2;c=3
$ if [ $a -lt $b -a $b -lt $c ]; then
echo "a < b < c"
else
echo "et non"
fi
a < b < c
$ if [ $a -lt $b ] && [ $b -lt $c ]; then
echo "a < b < c"
else
echo "et non"
fi
a < b < c
$ if (( ($a < $b) && ($b < $c) )); then
echo "a < b < c"
fi
a < b < c
$ if (($a < $b)) && (($b < $c)); then
echo "a < b < c"
fi
a < b < c
$ a=3;b=2;c=1
$ if [ ( $a -lt $b ) -a ( $b -lt $c ) ]; then
echo "a < b < c "
else
echo "not so "
fi
-bash: syntax error near unexpected token `$a'
$ if [ '( $a -lt $b ) -a ( $b -lt $c )' ]; then
echo "a < b < c "
else
echo "not so "
fi
a < b < c
$ if [ ( $a -lt $b ) -a ( $b -lt $c ) ]; then
echo "a < b < c "
else
echo "not so "
fi
not so
# démarre un commentaire
; séparateur de commande
{...} signifie un bloc de commande
(...) force l'exécution dans un sous-shell
&& ET logique (placé entre des commandes)
|| OU logique (placé entre des commandes)
~ remplacé par le répertoire de départ de l'utilisateur en cours
~user remplacé par le répertoire de départ de l'utilisateur user
/ séparateur de répertoire/fichier
$var remplacé par la variable 'var'
`...` execute une commande et substitue la sortie
$(...) syntaxe préférée de Bash pour la substitution de commande
$((...)) évalue une expression arithmétique entière
((...)) évalue une expression arithmétique entière dans une condition
' guillemet
" apostrophe
\ échappe le caractère suivant (annule une signification spéciale)
* joker
[...] ensemble de caractères joker
? caractère joker unique
& force l'exécution en arrière-plan de la commande
< redirrige l'entrée (stdin)
> redirige la sortie (stdout)
| pipe
! NOT logique de pipeline
$ echo \$1 \* \$b > \$c
$1 * $b > $c
$a * $b > $c
5 * 4 > 3
$1 * 4 > $3
Astuce d'Utilisation des Guillemets
You cant have Adrian's $1
> (hit control-c)
You can't have Adrian's $1
\'
't have " $1 " $1"}'
You can't have my $
You can't have my $
$ ls $file
/usr/local/bin/ls: ~/Desktop/: No such file or directory
$ ls ~/Desktop/
A File
A File
$ echo $file
/Users/saruman/Desktop
$ ls $file
A File
$ ls $file
A File
Guillemets sur Plusieurs Niveaux
A File
$ echo ls A\ Dir > script
$ ./script
ls: A: No such file or directory
ls: Dir: No such file or directory
ls A Dir
$ ./script
A File
$ mkdir melkor
$ mount -t afp afp://myuser:mypassword@melkor.mayo-family.com/myuser melkor
mount_afp: the mount flags are 0000 the altflags are 0020
$ ls
Desktop Documents Movies Pictures Sites melkor
Development Library Music Public bin osxfaq
$ mount-user -usage
monte le répertoire Départ de youruser à partir du serveur yourserver
Utilisation : mount-user [-p password] [-h host] [-u user]
[-p password] - utilise un mot de passe AFP si requis
[-h host] - remplace yourserver comme serveur à monter
[-u user] - remplace youruser comme utilisateur à monter
#!/bin/bash
# monte le répertoire Départ de l'utilisateur courant sur le serveur
# $ALM_SERVER into the mount $ALM_AFP_MOUNT/...
#
# fonction: usage ([error-message])
# affiche les lignes d'utilisation et quitte
# prend un message d'erreur d'options à afficher à la fin
# de la ligne usage
usage ()
{
echo "mount ${USER}'s home directory from server $ALM_SERVER"
echo ""
echo "Usage: ${0##*/} [-p password] [-h host] [-u user]"
echo " [-p password] - use an AFP password if required"
echo " [-h host] - override $ALM_SERVER as server to mount"
echo " [-u user] - override $USER as username to mount"
echo ""
if [ "$*" != "" ]; then echo "Error: $*."; fi
exit
}
# function: exit_if_set (current-value, parameter-description)
# appelée pour empêcher qu'un paramètre ait deux fois une valeur
exit_if_set ()
{
if [ "$1" != "" ]; then
usage "$2 a déjà la valeur $1"
else
return
fi
}
# traite chaque paramètre dans une boucle et déplace chaque itération
# de $2 -> $1
#
opt=""
while [ "$1" != "" ]
do
if [ "${1:0:1}" = "-" ]; then
# found a -
# option invalide
*) usage "invalid option $1";;
esac
else
case "$opt" in
# l'itération précédente était une option nécessitant une valeur, positionne la valeur
"-p") exit_if_set "$password" "password"; password="$1";;
"-h") exit_if_set "$host" "host"; host="$1";;
"-u") exit_if_set "$user" "user"; user="$1";;
"") usage "invalid value $1";;
esac
# une valeur a été trouvée pour -
# si le mot de passe est donné, ajoute ":" au début pour se conformer
# à la syntaxe de montage
if [ "$password" != "" ]; then
password=":"$password
fi
# vérifie si déjà monté
mounted=$(df | grep "$ALM_AFP_MOUNT/$host/$user")
# s'il n'est pas monté, on s'assure que le point de montage (répertoire) est dispo
# supprime juste au cas où il existerait en tant que fichier, et cache
# les erreurs
if [ ! "$mounted" ]; then
if [ ! -d $ALM_AFP_MOUNT/$host/$user ]; then
rm -f $ALM_AFP_MOUNT/$host/$user 2> /dev/null
rm -f $ALM_AFP_MOUNT/$host 2> /dev/null
mkdir -p $ALM_AFP_MOUNT/$host/$user
fi
echo "Mounting afp://$user$password@$host/$user on $ALM_AFP_MOUNT/$host/$user."
mount_afp afp://$user$password@$host/$user $ALM_AFP_MOUNT/$host/$user > /dev/null
if [ "$?" != "0" ]; then
echo "Erreur : le montage a échoué."
exit 255
fi
disktool -r
fi
# renvoie 0 si aucun montage n'a été effectué, 1 sinon
if [ ! "$mounted" ]; then
exit 1
else
exit 0
fi
$ ls -al /etc/lookupd/
total 4
drwxr-xr-x 3 root wheel 102 Apr 18 19:23 .
drwxr-xr-x 114 root wheel 3876 Aug 15 22:39 ..
-rw-r--r-- 1 root wheel 28 Aug 19 13:19 mounts
$ cat /etc/lookupd/mounts
LookupOrder Cache FF NI
RPCSERVER=-YES-
Réglage des Partages et Montages NFS
/Users -alldirs -maproot=nobody -network=192.168.0.0 -mask=255.255.255.0
/Users/Shared -ro -mapall=nobody
# local mounts
#
...
# NFS mounts
#
carcharoth:/Users /nfs/Carcharoth nfs -b,-i,-P 0 0
Cacher les Commandes Comprennant des Mots de Passe
Ceci est un fichier avec
des lignes séparées par deux lignes vides
et quelques lignes vides supplémentaires
aussi.
Ceci est un fichier avec
des lignes séparées par deux lignes vides
et quelques lignes vides supplémentaires
aussi.
Ce fichier a un nombre
de lignes, don certaines contiennent
le mot don, et don d'autres
ne le contiennent pas.
$ sed -n '/don/p' text
de lignes, don certaines contiennent
le mot don, et don d'autres
de lignes, dont certaines contiennent
le mot dont, et dont d'autres
this is this
and
that is that
$ sed -e 's/this/that/g' -e 's/that/twit/g' this
twit is twit
and
twit is twit
twit is twit
and
twit is twit
this is this
and
that is that
$ cat script
s/this/that/g
s/that/twit/g
$ sed -f script this
twit is twit
and
twit is twit
437
Sep 13 csv
Sep 13 double-space
Sep 13 many
Aug 30 script
Aug 30 text
Aug 30 this
Sep 13 xxx
Date: , File
Date: 13 Sep, File csv
Date: 13 Sep, File double-space
Date: 30 Aug, File script
Date: 30 Aug, File text
Date: 30 Aug, File this
Date: 13 Sep, File xxx
Ce fichier a un nombre
begin-marker
de lignes, dont certaines contiennent
le mot don, et dont certaines
end-marker
ne le contiennent pas.
$ awk '/begin-marker/,/end-marker/{print $0}' text
begin-marker
de lignes, dont certaines contiennent
le mot don, et dont certaines
end-marker
22
Ce fichier a un nombre
12
begin-marker
...
Ce fichier a un nombre
ne le contiennent pas.
line one
the second line
and the third
the fourth
line five
the six
and the last line
$ awk '/^the//^line/' many
line one
the second line
the fourth
line five
the six
LINE: line one
THE: the second line
THE: the fourth
LINE: line five
THE: the six
MATCHED: line one
MATCHED: the second line
MATCHED: the fourth
MATCHED: line five
MATCHED: the six
MATCHED: the second line
MATCHED: and the last line
scott,sheppard,mr,editor in chief,01
adrian,mayo,mr,editor,02
jan,forbes,miss,goddess,69
sheppard editor in chief
mayo editor
forbes goddess
sheppard editor in chief
mayo editor
forbes goddess
scott:sheppard,mr,editor in chief-01
adrian:mayo,mr,editor-02
jan:forbes,miss,goddess-69
$ awk 'BEGIN {FS=",|:|-"} {printf "1=%s, 2=%s, 3=%s, 4=%s, 5=%sn",$1, $2, $3, $4, $5}' csv2
1=scott, 2=sheppard, 3=mr, 4=editor in chief, 5=01
1=adrian, 2=mayo, 3=mr, 4=editor, 5=02
1=jan, 2=forbes, 3=miss, 4=goddess, 5=69