Soms wil je in een script weten of de invoer afkomstig is van een terminal (getypt door een gebruiker) of afkomstig is van een pipe (resultaten afkomstig van een andere opdracht). Dit lijkt eenvoudige, maar toch werd het zoeken op internet niet beloond met een oplossing. De volgende twee oplossingen kwamen tot stand na wat hersengymnastiek: via de stat opdracht en via informatie van het proc bestandssysteem.
language_tmp=$LANG LANG=us_US.utf-8Achteraf herstellen we de oorspronkelijke taal met:
LANG=$language_tmp
Daarna zoeken we uit wat is verbonden met de standaard uitvoer:
stdin="$(ls -l /dev/fd/0)" stdin="${stdin/*-> /}"Het bestand /dev/fd/0 is de standaard invoer, wat eigenlijk een koppeling (symbolic link) is. We gebruiken dus de opdracht ls om deze koppeling te achterhalen. In dit resultaat verwijderen we alles voor de tekens *->, wat ons uiteindelijk het gekoppelde bestand oplevert.
ftype="$(stat --printf=%F $stdin)"Nu kunnen we het bestandstype testen:
if [[ "$ftype" == 'character special file' ]]; then echo Terminal elif [[ "$ftype" == 'regular file' ]]; then echo Pipe: $stdin else echo Unknown: $stdin fiEven testen met:
dany@Dany-HP:~>sh ckpipe.sh
Terminal dany@Dany-HP:~>sh ckpipe.sh < ckpipe.sh
Pipe: /home/dany/ckpipe.sh
#!/bin/bash language_tmp=$LANG LANG=us_US.utf-8 stdin="$(ls -l /dev/fd/0)" stdin="${stdin/*-> /}" ftype="$(stat --printf=%F $stdin)" if [[ "$ftype" == 'character special file' ]]; then echo Terminal elif [[ "$ftype" == 'regular file' ]]; then echo Pipe: $stdin else echo Unknown: $stdin fi LANG=$language_tmp
dany@Dany-HP:~> ls -la /proc/self/fd
totaal 0
dr-x------ 2 dany users 0 4 nov 16:19 .
dr-xr-xr-x 7 dany users 0 4 nov 16:19 ..
lrwx------ 1 dany users 64 4 nov 16:19 0 -> /dev/pts/1
lrwx------ 1 dany users 64 4 nov 16:19 1 -> /dev/pts/1
lrwx------ 1 dany users 64 4 nov 16:19 2 -> /dev/pts/1
lr-x------ 1 dany users 64 4 nov 16:19 3 -> /proc/5013/fd
Zoals in de eerste oplossing bepalen we welk bestand de standaard invoer verzorgt:
stdin="$(ls -l /proc/self/fd/0)" stdin="${stdin/*-> /}"Daarna testen we of de naam van het bestand gekoppeld is aan een /dev/pts bestand:
if [[ "$stdin" =~ ^/dev/pts/[0-9] ]]; then echo Terminal else echo Pipe: $stdin fiTesten kan op een gelijkaardige manier:
dany@Dany-HP:~>sh ckpipe2.sh
Terminal dany@Dany-HP:~>sh ckpipe2.sh < ckpipe2.sh
Pipe: /home/dany/ckpipe2.sh
#!/bin/bash stdin="$(ls -l /proc/self/fd/0)" stdin="${stdin/*-> /}" if [[ "$stdin" =~ ^/dev/pts/[0-9] ]]; then echo Terminal else echo Pipe: $stdin fi