Comment détecter si l'input provient d'un argument, d'un file ou d'un terminal

En bash, existe-t-il un moyen de savoir si un script donné a été invoqué avec:

$ myscript.sh myfile 

ou:

 $ myscript.sh < myfile 

A l'intérieur de certains scripts j'ai toujours accédé au contenu de myfile avec $1 , mais maintenant j'aimerais changer le comportement comme des cas différents.

EDIT: Je voudrais aussi un troisième cas lorsqu'il est appelé sans redirection:

 $ myscript.sh 

EDIT : changé -t en -t 0 , qui détecte correctement l'input du terminal ou du file.

Je pense que la key ici est de savoir si votre consortingbution provient d'un terminal ou d'un file. Il y a un test pour cela ( man test , voir -t ).

En supposant que vous exécutez un script bash:

 if [ -t 0 ]; then echo "Input from terminal" if [ $# -eq 0 ]; then echo "No input files specified on command line. Error." >&2 else echo "Input file given on command line. It is $1" fi else echo "Input coming from stdin" fi 

Vous pouvez gérer les différents scénarios en remplaçant le code actuel par les instructions echo ci-dessus.

Mise à jour, script de test quickie:

 #!/bin/bash [ -t 0 ] && echo "t is true" || echo "t is false" 

Fonctionnement:

 $ test.sh testfile t is true $ test.sh < testfile t is false $ 

En général, les expressions $1 , $2 , etc. développent l'argument 1er, 2ème, etc. donné sur la command line du script.

Ainsi, lorsque vous appelez un script comme:

 myscript.sh myfile 

alors $1 dans le script s'étend à myfile (et $2 , $3 , etc. tous sont la string vide).

Lorsque vous appelez un script comme:

 myscript < myfile 

la redirection de STDIN à partir de myfile est effectuée par le shell parent, de sorte que le script est appelé sans argument et que $1 étendu à la string vide.