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 $fn
/Users/saruman/Documents/Essentials/todo.rtf

Extrayez le chemin d'accès (en-tête) :

% echo $fn:h
/Users/saruman/Documents/Essentials

Extrayez le nom de fichier (queue):

% echo $fn:t
todo.rtf

Extrayez l'extension :

% echo $fn:e
rtf

Retirez l'extension :

% echo $fn:r
/Users/saruman/Documents/Essentials/todo

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 $fn
/Users/saruman/Documents/Essentials/todo.rtf

% echo $fn:t:r
todo

Vous pouvez changer un nom de fichier en utilisant une substitution :

% echo $fn
/Users/saruman/Documents/Essentials/todo.rtf

% echo $fn:t:s/.rtf/.txt/
todo.txt

Batch Rename

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 rename
#!/bin/tcsh
set fn_new={$1:r}.$2
echo rename $1 $fn_new
mv $1 $fn_new

Ajoutez la commande 'find' des semaines 1 et 13 pour renommer en mode batch (arrière-plan) :

% ls
a.htm b.htm c.htm

% find . -name "*.htm" -exec rename {} html ;
rename ./a.htm ./a.html
rename ./b.htm ./b.html
rename ./c.htm ./c.html

% ls
a.html b.html c.html

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 *.html
a.html b.html c.html

% ls !*:r
ls *
a.html b.html c.html rename rename2

et

% ls *.htm
ls: No match.

% ls !*:r.html
ls *.html
a.html b.html c.html

Je vous laisserai deviner ce qui va arriver.


basename et dirname

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
/Users/saruman/Documents/Essentials/todo.rtf

% echo `basename $fn`
todo.rtf

% echo `dirname $fn`
/Users/saruman/Documents/Essentials

'find' étendu

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" less

va les afficher.


De Mac vers Unix

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

De Unix vers Mac

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

Batch Rename

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 rtf

va changer *.txt en *.rtf dans le répertoire courant.


Utiliser les apostrophes

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...)


Activer 'at'

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/atrun

pour 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/spool

3. 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.)


Utiliser 'at'

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-file
open /Applications/Clock.app

% at -f at-file 21:30
Job a010b400a.000 will be executed using /bin/sh

A 21:30, l'application Horloge de OS X sera lancée.


'atq' et 'atrm'

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.000

en donnant le numéro du job qui est plutôt vilain.


Plus sur 'at'

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 :

$HOME

Le temps peut être spécifié par rapport à l'instant présent avec :

at -f at-file now + 10 minutes
at -f at-file now + 1 hour

Le calendrier Unix

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 calendar

10 April Jeudi's job
20 April Sunday's job
26 April Saturday's job

04/01 April Fool
04/20 Sunday's job
04/29 Dentist

Affichez les évènements pour une date donnée (spécifiée comme MMJJ) avec les commandes suivantes :

% calendar -d 0410
10 April Jeudi's job

% calendar -d 0429
04/29 Dentist

Pour aujourd'hui (le 20 avril dans cet exemple), vous pouvez vous passer de préciser la date :

% calendar
20 April Sunday's job
04/20 Sunday's job

Si le fichier n'est pas 'calendar' dans le répertoire actuel, utilisez l'option '-f' :

% calendar -f /path/name/file-name -d 0429
04/29 Dentist

Unix a des fichiers de calendrier déjà prêts dans :

/usr/share/calendar

Par 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

ping

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.com
PING apple.com (17.254.3.183): 56 data bytes
64 bytes from 17.254.3.183: icmp_seq=0 ttl=45 time=165.922 ms
64 bytes from 17.254.3.183: icmp_seq=1 ttl=45 time=165.541 ms

L'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.)


Astuces pour ping

Essayer de pinger toutes les machines sur votre réseau local pour voir celles qui utilisent Rendezvous :

% ping 224.0.0.251

Pingez l'adresse de broadcast de votre sous réseau local pour découvrir toutes les machines qui s'y trouvent :

% ping 10.0.1.255

ou

% ping 192.168.1.255

Regardez si votre routeur répond à :

% ping 0

et qui répond à :

% ping 255.255.255.255

Vous pouvez pinger une machine AppleTalk avec 'appleping'.


traceroute

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

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 -a

vous 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.
mayo-family.com has address 64.84.37.15
mayo-family.com mail is handled (pri=10) by mail.hostwizard.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
183.3.254.17.IN-ADDR.ARPA domain name pointer apple.com

(Voir aussi la Semaine 42 pour plus de conseils Internet.)


Des astuces pour 'host'

'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 :

  • A = adresse IP
  • MX = serveur mail
  • NS = serveur de nom

'dig' et 'nslookup'

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.


'whois'

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...


Shells secondaires

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


Redirection

Ceci s'applique au shell 'tcsh'.

Pour rediriger une sortie standard, utilisez '>'. Ex :

ls -al * > list

Les 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 >& list

Pour 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


Redirection 2

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.err

Pour 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


Redirection 3

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.err

Mac 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


Comment tuer un job

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 15048

Remarquez 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 Clock

qui 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.


Beaucoup de façons de tuer

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 -l

liste tous les signaux disponibles, et :

% man sigaction

donne plus de détail.


Le Script Assassin

Voici un script pratique pour tuer des processus par leur nom :

% cat killer
#!/bin/sh
kill $(ps auxww | grep -i $1 | grep -v $1 | awk '{print $2}')

% killer clock
*gone!*

N'oubliez pas de rendre le script exécutable.


Trouver votre victime

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`'
% alias nfs-export 'sudo kill -HUP `cat /var/run/mountd.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.


Le Script de Pendaison

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 lookupd
redémarrage du démon lookupd

N'oubliez pas de rendre le script exécutable.


Démarrer et Arrêter Apache

Pour démarrer et arrêter Apache à partir de la ligne de commande, utilisez l'utilitaire de contrôle d'Apache :

% sudo apachectl start
/usr/sbin/apachectl start: httpd started

% sudo apachectl stop
/usr/sbin/apachectl stop: httpd stopped

Pour faire en sorte qu'Apache démarre lorsque vous démarrez votre Mac, éditez le fichier :

/etc/hostconfig

en étant sous root, et changez

WEBSERVER=-NO-

en

WEBSERVER=-YES-

Redémarrer Apache

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
/usr/sbin/apachectl graceful: httpd gracefully restarted

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.conf

Remplacez 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"

Le manuel Apache

Vous pouvez accéder au manuel Apache en ligne avec l'URL : http://localhost/manual/


Les fichiers d'accès Apache

Apache écrit les informations d'accès dans :

/private/var/log/httpd/error_log

et :

/private/var/log/httpd/access_log

Examinez 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.conf

Cherchez :

CustomLog "/private/var/log/httpd/access_log" common

Et 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
which: shell built-in command.

% which \which
/usr/bin/which

et essayez ceci :
% \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 $PATH
% echo $path

De 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'

% rehash

S'il n'y a pas de réponse, c'est que tout va bien.

Essayez ceci :

% hashstat

umask

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-dir

et les fichiers ont les permissions suivantes :

-rw-rw-rw- 1 saruman staff 0 Jun 9 11:16 test-file

En 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'

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

exec

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

Démarrage du Shell

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.cshrc
/etc/csh.login

~/.tcshrc
~/.login

Vous 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.


tcshrc et cshrc

Pour une compatibilité en amont avec le shell 'csh' (à partir duquel est dérivé le shell 'tcsh'), le fichier de script :

~/.cshrc

peut 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.login
~/.login

alors 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
XTerm*.LoginShell: True

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.login
~/.login

Dans 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}:xxx

qui 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

if ($?prompt) set interactive

Puis entourez toutes les commandes exclusivement interactives avec :

if ($?interactive) then

... lieu des commandes interactives...

endif

'xargs'

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 {} ;
./week13/thursday.ws
./week21/thursday.ws
./week5/friday.ws
./week5/thursday.ws
./week9/monday.ws

Le même effet peut être obtenu en montant un 'pipe' avec 'xargs' :

% find . -iname "*.ws" | xargs grep -il warning
./week13/thursday.ws
./week21/thursday.ws
./week5/friday.ws
./week5/thursday.ws
./week9/monday.ws

'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 .......

'xargs' vs '-exec'

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.


Les options de 'xargs'

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-script

L'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
grep -il warning ./index.ws ./week1/friday.ws ./week1/monday.ws
./week1/thursday.ws ./week1/tuesday.ws ./week1/wednesday.ws
./week10/friday.ws ./week10/monday.ws ./week10/thursday.ws
...
./week8/friday.ws ./week8/monday.ws ./week8/thursday.ws
./week8/tuesday.ws ./week8/wednesday.ws ./week9/friday.ws
./week9/monday.ws ./week9/thursday.ws ./week9/tuesday.ws

./week9/wednesday.ws
./week13/thursday.ws
./week21/thursday.ws
./week5/friday.ws
./week5/thursday.ws
./week9/monday.ws

Trop de fichiers?

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

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'.


Mouvement du Curseur

Apprenez les touches de mouvement du curseur. Les plus utiles sont :

{ retour au début du paragraphe
( retour au début de la phrase
- retour au début de la ligne précédente
^ retour au début de la ligne
b retour au début du mot
w avance au début du mot
$ avance vers la fin de la ligne
+ avance au début de la ligne suivante
) avance au début de la prochaine phrase
} avance au début du prochain paragraphe
G vers la fin du fichier

(plus les touches curseur évidentes).


Couper, copier et coller

Utiliser couper, copier et coller :

d coupe (delete)
y copie (yank)
p colle (paste—au-dessous de la ligne courante, et P colle au-dessus)

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 ligne
d) efface jusqu'à la fin de la phrase
(y) copie la phrase entière, quel que soit l'endroit du curseur dans la phrase

Raccourcis :

dd est le raccourci pour effacer la ligne courante
yy est le raccourci pour copier la ligne courante

Utilisez les 26 buffers

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é "a
"ap colle le texte qui se trouve dans le buffer "a

Notez 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

Signets

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 :


ma

"by'a

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 curseur
'a déplace vers le début de la ligne marquée
`a déplace vers la position du caractère marqué dans la ligne marquée

Constituez 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 -ch
15M ./Pictures/complete/ferdi-coll3.psd
30M ./Pictures/complete/ferdi-cool.psd
1.7M ./Pictures/complete/ferdi-gala.psd
...
600k ./Pictures/web-site/misc/web5.psd
72k ./Pictures/web-site/osxfaq/banner1.psd
48k ./Pictures/web-site/osxfaq/banner2.psd
96k ./Pictures/web-site/osxfaq/btn-.psd
28k ./Pictures/web-site/osxfaq/end.psd
316M total

Voilà ! - 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 +40000

Pour appliquer ceci à des répertoires, utilisez :

% du -k ~ | egrep "^[0-9]{6,}"
139252 /Users/saruman/Library
267020 /Users/saruman/Pictures/complete
357432 /Users/saruman/Pictures/iPhoto Library/2001
214084 /Users/saruman/Pictures/iPhoto Library/2002
195788 /Users/saruman/Pictures/iPhoto Library/2003/01
124948 /Users/saruman/Pictures/iPhoto Library/2003/05
149976 /Users/saruman/Pictures/iPhoto Library/2003/06
545460 /Users/saruman/Pictures/iPhoto Library/2003
1149224 /Users/saruman/Pictures/iPhoto Library
1548924 /Users/saruman/Pictures
1902804 /Users/saruman

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-file

En utilisant 'tr' :

% tr -s \n < in-file > out-file

Si le fichier comporte des lignes contenant des espaces :

% sed '/^[ ]*$/d' in-file > out-file

Si les lignes contiennent aussi des tabulations :

% sed '/^[ t]*$/d' in-file > out-file

MAIS, 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-file

Comment 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)" *.txt

Le '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.


...Redémarrer un démon

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.pid
11024
/usr/sbin/sendmail -L mta -bd -q30m

Changez le script pour utiliser 'head' au lieu de 'cat', de façon à couper les lignes supplémentaires :

...
sudo kill -HUP `head -n1 /var/run/$1.pid`
...

Editer plusieurs fichiers

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.

:new

sépare l'écran en deux moitiés et crée un nouveau buffer d'édition, et :

:new file-1

sé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.


Diviser l'écran verticalement

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.


Comparer deux fichiers

La commande :

% vimdiff file-1 file-2

va 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-2

ou

:vert diffsplit file-2

pour charger file-2 et voir les différences.


Edition par lot de plusieurs fichiers

La commande :

% vim f1 f2 f3 f4 f5

va 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
:prev - précédent 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 :

:buffers

et passez à un buffer spécifique (buffer 2, par exemple) avec :

:b2

Raccourcis de Vim

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
-r = lecture seule
-x = exportée (variable d'environnement)

% declare -rx ENV=cant_change

Redirection et Pipes

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

Fichiers de démarrage

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 -l
/etc/csh.cshrc
/etc/csh.login
~/.tcshrc
~/.login

Shell de connexion bash :

% bash --login
/etc/profile
~/.bash_profile

Shell de non-connexion tcsh :

% tcsh
/etc/csh.cshrc
~/.tcshrc

Shell de connexion bash :

% bash
~/.bashrc

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
% ls Zb^D"

(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 Z
% mv Zb^D" z-file

Si la partie visible du nom de fichier n'est pas unique :

% ls d
DB)b^D"o#?b^B, DB4#^ Danger

alors 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 d
DB)b^D"o#?b^B, DB4#^ Danger

utilisez 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 ;

Un petit coup de 'fsck'

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 -y

Pour réparer d'autres partitions, tapez :

# fsck_hfs -y /dev/disk0sX

où X représente le numéro de tranche (partition) identifié par :

% pdisk
tapez L
lisez le n° de partition dans la colonne de gauche au côté du nom de volume
tapez q pour quitter.

% mount -uw /
% reboot

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).


Corbeille récalcitrante

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).


Le Nom Executable

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 usage
#!/bin/sh
echo "Usage 1: $0"
echo "Usage 2: ${0##*/}"

$ ~/Development/test/usage
Usage 1: /Users/saruman/Development/test/usage
Usage 2: usage

Mac OS X Unix Tutorial 9 - Shell Scripting 2. New 8 Septembre.


Conditions Complexes

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" = "" ]; then

Le '-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" ]; then

Mac OS X Unix Tutorial 9 - Shell Scripting 2. New 8 Septembre.


Tester qu'un Volume est Monté

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.


Monter un Volume AFP

Un volume AppleShare peut être monté avec les lignes suivantes :

mkdir /Volumes/$USER
mount_afp afp://$USER@carcharoth.mayo-family.com/$USER /Volumes/$USER > /dev/null

Cela 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 /Volumes


$ ./mount-user
Mounting /Volumes/saruman

$ ls /Volumes
saruman

$ ./mount
/Volumes/saruman already mounted

Mac 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.


Liens Symboliques

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
Je suis le fichier original
% cat link-file
Je suis le fichier original

'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 d