Vous êtes sur la page 1sur 10

Script shell 1

Il s’agit du premier de trois laboratoires sur Shell Scripting. Les scripts shell nous permettent
d’écrire des scripts qui effectuent des tâches dans le terminal Unix. Tout comme les fichiers
MATLAB et les macros SAC, nous pouvons faire des choses comme définir des variables et
contrôler le flux en utilisant des instructions if et des boucles, ce qui nous donne des outils
plus puissants pour que l’ordinateur manipule des fichiers et des données. Sans scripts shell,
si vous deviez traiter 1000 fichiers de données avec un seul programme, vous devrez taper
la même commande 1000 fois, ce qui vous prendrait beaucoup de temps et risquerait
d’entraîner une erreur. Un script shell vous permet de faire la même chose avec une boucle,
éliminant les erreurs de frappe et accélérant considérablement le processus..m

Dans ce document, je vais présenter un certain nombre de commandes et donner des


exemples simples de beaucoup d’entre elles. Vous devez taper chacun des exemples simples
dans un fichier de script shell sur votre ordinateur, les exécuter pour vous assurer que tout
fonctionne, puis modifier certaines choses pour vous assurer que vous savez comment
fonctionnent les différentes commandes, en particulier pour les variables shell et les chaînes
de citation. C’est votre chance d’expérimenter avec la façon dont les commandes sont
utilisées. Dans les deux prochains laboratoires, nous écrirons des scripts plus compliqués
qui utilisent les commandes d’aujourd’hui.

Shell Scripts
Pour créer un script shell, utilisez votre éditeur de texte préféré pour ouvrir un nouveau
fichier appelé (n’hésitez pas à changer le nom si vous le souhaitez). Vous pouvez utiliser
n’importe quel shell que vous aimez, et il est courant d’utiliser le shell pour lequel le script
est écrit comme extension de fichier. Beaucoup de gens ont tendance à écrire leurs scripts
shell dans le shell C ou le shell Bourne, car de nombreuses cloches et sifflets interactifs qui
ont été ajoutés dans les autres shells ne sont pas couramment utilisés lors de l’écriture de
scripts shell (les et shells sont des sur-ensembles des commandes et, respectivement). Ainsi,
ils utilisent le plus petit dénominateur commun pour rendre les choses aussi compatibles
que possible avec les systèmes plus anciens au cas où ils devraient exécuter leur script sur
un autre ordinateur. Cependant, je noterai que sur le Mac, l’exécution ne fait que fonctionner
et ne fonctionne que, donc dans de nombreux cas, les deux sont identiques. Je vais essayer
de souligner certaines des différences entre les différentes coquilles au fur et à mesure, mais
le texte que je tape sera en général pour la coque C. C’est une bonne idée de se familiariser
avec la syntaxe des deux shells au cas où vous êtes sur un ordinateur avec un seul des
shells, ou si vous obtenez un script shell de quelqu’un
d’autre.example.cshtcshbashcshshcshtcshshbash
Une fois votre fichier ouvert dans un éditeur de texte, tapez ce qui suit comme première
ligne :

#!/bin/csh

Il s’agit généralement de la première ligne d’un script shell, et si elle est présente, elle doit
être la première ligne du fichier et ne pas avoir d’espaces de début. Cette ligne indique à
l’ordinateur lorsqu’il exécute votre script shell qu’il doit interpréter toutes les commandes à
l’aide du shell C. Il indique également à la personne qui lit le code que le script est destiné à
être interprété par le shell C, afin qu’elle sache quelle syntaxe utiliser lors de la modification.
Rappelez-vous qu’il existe de légères différences entre les différents shells, il est donc
important d’utiliser la syntaxe qui correspond à ce shell. Si vous souhaitez que votre script
shell s’exécute sans exécuter le fichier de démarrage par défaut, la première ligne doit
être .#!/bin/csh -f

Cette ligne pour spécifier la commande destinée à interpréter les commandes est
généralement présente dans tous les autres types de langages de script, tels que Perl et
Python. Lorsqu’un script est exécuté dans le terminal, le shell lit cette première ligne, puis
appelle le programme correspondant à cette ligne avec les lignes restantes du script en
entrée. Cette ligne n’est pas strictement nécessaire, mais si nous ne l’incluons pas, nous
devons spécifier le programme lors de l’exécution du script. Pour notre script shell, nous
aurions besoin de taper dans le terminal sans cette première ligne.csh example.csh

Après cette ligne, vous entrerez les commandes que vous souhaitez que le shell exécute
lorsque vous exécutez ce script. Toutes les commandes que nous avons apprises jusqu’à
présent peuvent être placées dans un script shell, donc pour commencer, mettez des
commandes Unix valides dans ce fichier (des choses comme et qui impriment des choses à
l’écran sont de bonnes choses à mettre ici pendant que vous apprenez comment
fonctionnent les scripts shell). Vous pouvez inclure des commentaires en utilisant pour
désigner un commentaire.lscat#

Exécution d’un script Shell


Une fois que vous avez entré quelques commandes, enregistrez votre fichier et revenez au
terminal. Il existe plusieurs façons d’exécuter votre script. Tout d’abord, comme mentionné
ci-dessus, vous pouvez taper , qui appelle avec votre fichier comme entrée. Cela fonctionne
que vous incluiez ou non la commande shell comme première ligne du fichier. Cependant, si
vous ne voulez pas taper avant chaque script que nous exécuteons, nous pouvons éviter
cela. Tout d’abord, vous devez vous accorder des autorisations d’exécution sur votre fichier
(si vous n’avez pas d’autorisations d’exécution, utilisez-le pour le faire). Ensuite, vous
pouvez entrer dans le terminal, qui devrait exécuter votre script. (Remarque: si vous donnez
l’extension au fichier, le shell peut généralement déterminer ce qu’il faut utiliser pour
exécuter votre script shell si aucune commande n’est spécifiée dans le script ou la ligne de
commande. Cependant, il est généralement de bonne pratique de programmation de
spécifier la commande dans la première ligne de tout
script.)csh example.cshcshcshchmod./example.csh.csh

Pourquoi?./example.csh
Pourquoi devons-nous entrer la période avant de donner le nom du script? Si vous essayez
d’exécuter votre script shell sans lui, cela ne fonctionnera pas (vous verrez un message
d’erreur « Commande introuvable »). Cela a à voir avec la façon dont les systèmes Unix
recherchent les commandes.

Chaque fois que vous tapez une commande dans Unix, il recherche une commande qui
correspond à la commande que vous avez entrée à certains endroits et dans un certain
ordre. Il décide des lieux et de l’ordre à l’aide de ce que l’on appelle une variable
d’environnement appelée . Une variable d’environnement est une variable prédéfinie qui
fournit des informations sur le shell avec lequel vous travaillez. Les exemples de variables
d’environnement incluent des informations telles que votre nom de connexion () et
l’emplacement de votre répertoire personnel (). Ceux-ci sont très utiles pour créer des
scripts shell qui fonctionnent pour différents utilisateurs sur différents systèmes, au cas où
la configuration spécifique d’un ordinateur est différente de celle où vous avez écrit le
script.PATHUSERHOME

Une variable d’environnement très importante est . est une chaîne de répertoires dans
laquelle vos shells recherchent les commandes qui correspondent à celle que vous avez
tapée dans le terminal. Lorsque vous tapez une commande, le shell commence à parcourir
les répertoires jusqu’à ce qu’il trouve une commande qui correspond à celle que vous avez
entrée. Il commence dans le premier répertoire, et s’il ne trouve pas de commande
correspondant à celle que vous avez tapée, il passe au suivant, en continuant tout au long de
la liste des répertoires. S’il arrive à la fin de tous les répertoires sans en trouver un, il donne
un message d’erreur « Commande introuvable ». Notez que cela s’applique
à toute commande entrée : les commandes shell standard comme et sont également des
programmes qui doivent être localisés avant d’être exécutés, et ils se trouvent dans des
répertoires dans votre chemin.PATHPATHPATHPATHlscd

Vous pouvez regarder votre chemin à l’aide de la commande, qui répertoriera toutes les
variables d’environnement (il y en a beaucoup). Nous sommes intéressés par , ce qui peut
nécessiter que vous défiliez un peu vers le haut. Vous pouvez également y accéder en
entrant dans le terminal. est une commande utile dans les scripts shell, car elle peut être
utilisée pour imprimer des éléments à l’écran (y compris des variables, qui peuvent vous
aider à déboguer votre script). Dans les deux cas, vous verrez une longue liste de
répertoires, chacun séparé par un deux-points (par exemple, le début de peut être ). Il s’agit
des répertoires dans lesquels le shell recherche les commandes et de l’ordre dans lequel
elles sont
recherchées.envPATHPATHecho  $PATHechoPATH/usr/local/bin:/usr/bin:/
bin:...

Si vous souhaitez savoir si une commande se trouve dans l’un des répertoires de votre
chemin d’accès, utilisez la commande. imprime le chemin d’accès complet à une commande
entrée et constitue un moyen pratique de déterminer (1) si une commande se trouve dans
votre chemin d’accès et (2) si une commande se trouve dans plusieurs répertoires de votre
chemin, celui qui sera exécuté.whichwhich

Notez que ne contient pas votre répertoire actuel, vous avez donc obtenu une erreur lorsqu’il
a recherché cette commande. Pour indiquer au shell de traiter example.csh comme un
exécutable, nous utilisons la notation « dot » pour indiquer au shell que l’exécutable que
nous voulons exécuter se trouve dans le répertoire actif. Cela est généralement vrai pour
d’autres types d’exécutables et de scripts, tels que les scripts AWK que nous avons examinés
la semaine dernière.PATH./example.csh

Il y a un moyen d’éviter de taper à chaque fois : on peut ajouter à notre chemin (sous Unix se
réfère au répertoire actuel), de sorte que le shell saura regarder dans le répertoire courant.
Ceci est généralement mal vu par les administrateurs système, car quelqu’un pourrait mettre
des programmes malveillants dans l’un de nos répertoires qui est exécuté à cause de cela (ce
qui en fait un risque de sécurité). Je ne mets pas « point » dans mon chemin pour cette
raison, et cela ne me dérange pas vraiment de taper deux caractères supplémentaires. Vous
pouvez ajouter des répertoires supplémentaires à votre chemin d’accès en tapant (vous
apprendrez ce que cela fait sous peu; en gros, vous ajoutez un deux-points et un nom de
répertoire à la chaîne existante stockée dans ). Cela ne prendra effet que dans le présent
terminal; Pour que l’effet ait lieu dans les sessions futures, vous devrez ajouter cette ligne à
votre fichier de démarrage../example.csh..set  PATH = ${PATH}:<directory>PATH

Variables
As we have seen countless times, variables are a powerful tool for programming as they can
save typing and make programs more flexible and robust. Variables in the shell must start
with a letter, and they are defined using , for instance sets to be the string . To access the
value of the variable at another time, use . Thus, we might write a shell script to copy a file to
a new directory as follows:set <name> = <value>set x = 1x1$x

#!/bin/csh
# shell script to copy a file to a new location

set file = myfile.txt

echo "Copying $file to home directory"


cp $file $HOME

This script is rather simple, but illustrates how variables are used in the shell. First, note that
by using a variable, we only have to change the initial place where was set in our script (I
hope the usefulness of this is clear from our previous programming experience). Then, both
the statement and the copy command use the correct filename. Note that I also used the
environment variable to designate the target directory for the copy command. By
using instead of the path to my home directory, this means that this script will work on any
Unix machine, regardless of how the home directories are set up.fileechoHOMEHOME

set is used to set the value of a variable in the current instance of the shell. However, if your
shell script calls some other shell script, you will not have access to that variable within that
shell script. To make a variable visible to other instances of the shell, you need to add it to
the list of environment variables, as environment variables are passed on when a shell
creates another shell. To set an environment variable, type . Try this, and then type to verify
that the variable has been added to the list of environment
variables.setenv <name> <variable>env

If you are using , the syntax for defining variables is different. Regular variables are just set
normally in the shell (), while environment variables are set using : . Note that you cannot
have spaces for setting variables in like you can using the C
shell.bashx=1exportexport  x=1bash

Quoting Rules in Shell Scripts


Note that in the previous example, I was able to print out the value of in my print statement.
This is because I used double quotes to designate the string to be printed out. What if I
wanted to literally print out “$file” in that echo statement? Or what if you want to set a
variable equal to some special character? We have already seen that one way to include
spaces and other special characters in commands is to use the backslash immediately before
the character. You can also put quotes, either single or double, around the entire string to
have the shell interpret the entire string as a single argument in the event that your variable
name include spaces.file\

The shell has complex rules for using quotes to denote commands and variable names. In
particular, The shell treats single and double quotes in a different manner when interpreting
the contents with respect to variable names. If you include a variable value inside double
quotes, then the shell will replace the variable with its contents within that string. This was
illustrated above. A further example:$x

#!/bin/csh
set x = 1
echo "number$x"

will print to the terminal. If you would like to include further text immediately after the
variable, use braces to enclose the variable name, like :number1${x}

#!/bin/csh
set x = 1
echo "number${x}2"

to print to the terminal. However, if you want the literal characters to appear for
the command, then we use single quotes:number12${x}echo

#!/bin/csh
set x = 1
echo 'number${x}2'

which will print to the terminal. This quoting works the same for setting variables (to set a
variable to the string , put it in single quotes).number${x}2$x

Including quotes within a string is a bit trickier. One way to do this is to use the backslash to
precede a quote to put it into the string. You can also put single quotes within a double
quote string, and vice versa. However, neither of these work if you need to put quotes
around a variable name to get the shell to substitute that variable. In this particular case, the
way to put quotes inside of a quoted string is to concatenate several strings that use quotes
appropriately: for example, concatenates three strings together: the first is (the result of , or
using a single quote within a double quote string), the second is , which uses single quotes
to avoid expanding the shell variable within, and the final string is again (the result of ). The
result is that the shell will print to the terminal.echo "'"'$x'"'"'"'"$x'"'"'$x'

One other quoting trick: if we want to include the output of a Unix command in a string,
surround the command with backwards quotes (). For instance, will print “The current
directory is ” followed by whatever the output of the command
is.`echo "The current directory is `pwd`"pwd

Practice using quotes to get the following to print out in the terminal using . Precede the
command with the commands and so that you will have some variables to work with. I will
refer to the values stored in the variables x and y in italics, while I will refer to the actual
letters x and y in regular script. Other text in italics should print what that text refers to on
the screen.echoset x = 1set y = 2

 The final score is y to x


 Shell scripts print variables using $x and $y
 x can’t be less than y
 Don’t forget quotes when printing “$x” and “$y”
 “I won’t make mistakes when using x and $y”
 The current path is the current path
 My home directory is your home directory
 The file ‘example.csh’ contains the echo command number of times echo appears in
example.csh times

Using quotes properly in a shell script can be tricky, but it is very useful as it lets you control
string output. Since much of automating tasks involves reading and saving things from files,
being able to specify file names from variables is essential (otherwise you would need to
rewrite your shell script every time you wanted to change the target files). Thus, using these
quoting rules to correctly construct strings with appropriate file names is a necessary skill
for shell scripting.

Input Arguments
Other uses of variables in shell scripts allow you to make shell scripts into functions. This
lets you use one shell script to perform a task that might have different input values. When
you call a shell script, you can give it any number of input arguments as follows:

$ ./example.csh <var1> <var2> ...

Within the shell script, you can access these variables using , , etc. As a simple example, the
following shell script takes three options, with the first option specifying a search string, and
the second two options specifying files in which to search for that string using $1$2grep

#!/bin/csh
grep $1 $2 $3

These variables behave exactly like regular variable set with the command. However, note
that these have a different meaning than in AWK, so you need to be particularly careful if you
need to write an AWK program within a shell script (you need to use single quotes around
anything that you plan to pass to AWK).set

Math with Shell Variables


In the C shell (not in – the syntax for doing arithmetic in is totally different, and won’t be
covered here) you can do math with variables if you begin the line with . For example, the
following script should print out 1, then 2:bashbash@

#!/bin/csh
set x = 1
echo $x
@ x = $x + 1
echo $x

Note that you must have a space between and the addition sign, and the one and the
addition sign as otherwise the shell thinks you want to access the variable . You can also
increment a variable by one using and decrement a variable by one using . In these cases, no
spaces are necessary.$x$x+1@ x++@ x--

There are also comparison operators for variables, which do string comparisons. tests for
equality between two strings, tests if two strings are different, compares a string to a string
pattern on the right (i.e. can contain wildcards), and tests if a string does not match a string
pattern. Also it is important to note that all arithmetic is integer arithmetic, meaning that you
cannot do math with a decimal value (you will get an error), and division always returns an
integer value (i.e. 3/2=1 in a shell script). Valid arithmetic operators include , , , , , ,
and (modulo or remainder). We will see how to do non-integer arithmetic a bit later (it
requires more complicated commands than integer math).==!=~!~+-*/++--%

Array Variables
In addition to scalar variables, you can define arrays in a shell script. As with scalar variables,
all array variables are stored as strings, but you can do integer arithmetic with them. Arrays
are defined and you can access the elements as follows:

#!/bin/csh
set x = (1 2 3)
echo $x
echo $x[1]
@ x[1] = $x[1] + 1
echo $x

Indices in the shell begin at one, just like the indices for arrays in MATLAB. However, unlike
MATLAB you cannot do array math (you need to iterate over all of the indices of an array to
change everything) or floating point arithmetic, only integer arithmetic.

Autres façons spéciales d’accéder aux variables de tableau : renvoie une liste de tous les
éléments du tableau , tandis que si vous donnez une plage de nombres, il renverra une
tranche du tableau. renvoie le nombre d’éléments de la liste. Vous pouvez également utiliser
un tableau pour définir un autre tableau, par exemple en rendant égal au tableau contenant
les cinq premiers éléments de . Les parenthèses sont importantes ici, car elles indiquent au
shell que vous voulez être un tableau. D’autres astuces utiles concernant les variables et les
tableaux dans le shell C incluent , qui vous indique si une variable est définie (elle renvoie 1
si elle l’est, zéro si elle ne l’est pas).$x[*]$x$x[2-4]$#xset  y = ($x[1-5])yxy$?x

Une autre application utile des tableaux dans le shell C est que l’utilisation de , plutôt que ,
vous donne le chemin d’accès comme un tableau de chaînes au lieu d’une longue chaîne
avec des deux-points séparant les entrées. Cela peut être beaucoup plus utile dans un script
shell par rapport à la version standard avec les entrées séparées par des deux-
points.pathPATH

Mathématiques en virgule flottante


J’ai rarement besoin de faire des calculs en virgule flottante dans la coquille, mais si jamais je
le fais, cela peut être fait avec des citations. C’est un peu gênant, mais possible, donc si
jamais vous avez besoin de faire des mathématiques de base dans un script shell, vous
pouvez le faire. Il utilise la commande Unix Basic Calculator . peut être exécuté de manière
interactive ou exécuter des commandes fournies dans un fichier ou à partir d’une entrée
standard. La version d’entrée standard est la plus utile dans les scripts shell. Par exemple,
pour ajouter deux nombres décimaux et stocker en tant que variable,bcbc

#!/bin/csh
set a = 1.4
set b = 2.2
set c = `echo "$a + $b" | bc`
echo $c

Comme vous pouvez le voir, c’est un peu gênant car vous devez utiliser des guillemets à
l’envers pour obtenir la sortie standard de dans la commande pour définir la valeur de la
variable . est utile pour un certain nombre d’autres choses, telles que faire des comparaisons
inférieures et supérieures aux types, que nous verrons dans la classe suivante lorsque nous
couvrirons les conditions et les boucles dans les scripts shell.bccbc

Résumé
Nous avons introduit un certain nombre de commandes et de concepts utiles pour écrire des
scripts shell dans le shell C (et le shell Tenex C par extension). Bien que ces types de
commandes soient généralement utilisés dans l’écriture de scripts shell, ils sont également
valables dans les sessions de terminal interactif. Cela signifie que vous pouvez définir des
variables dans n’importe quelle session de terminal, et vous pouvez également le faire dans
les fichiers de démarrage pour avoir des variables disponibles pour votre utilisation lors de
l’utilisation interactive du shell.

 echo
 env et variables d’environnement
 set
 setenv
 PATH et path
 Variables, arguments d’entrée et tableaux
 @ (pour l’arithmétique variable)
 Devis (versions double, simple et à l’envers)
 bc

Vous aimerez peut-être aussi