miércoles, 10 de febrero de 2010

Determinar Si Una Entrada de Shell Viene del Terminal o de un Pipe

Usando el comando stat e información del archivo de sistema proc, se puede determinar si la entrada de una sentencia (script) viene de un terminal o de un pipe.

La primera solución usa el comando stat para determinar que tipo de archivo esta conectado a la entrada estándar. Primero se busca que esta conectado a la salida estándar:

stdin="$(ls -l /dev/fd/0)"
stdin="${stdin/*-> /}"

El archivo /dev/fd/0 es la entrada estándar, el cual es un enlace simbólico, entonces se usa ls para obtener el archivo que esta enlazado. Entonces se remueve todo lo que coincida con *-> desde el comienzo del valor, lo cual te deja con el enlace al archivo.

Ahora se usa el comando stat para obtener el tipo de archivo:

ftype="$(stat --printf=%F $stdin)"

Luego se prueba el tipo de archivo:

if   [[ "$ftype" == 'character special file' ]]; then
echo Terminal
elif [[ "$ftype" == 'regular file' ]]; then
echo Pipe: $stdin
else
echo Unknown: $stdin
fi

Se puede probarlo vía:

$ sh ckpipe.sh
Terminal
$ sh ckpipe.sh "<"ckpipe.sh Pipe: .../ckpipe/ckpipe.sh
La siguiente solución es usando información del archivo proc. En el archivo proc los archivos para cada proceso aparecen en el directorio /proc/PROCESS_ID/fd:
$ ls -la /proc/self/fd
total 0
dr-x------ 2 mitch users  0 2010-02-10 11:04 .
dr-xr-xr-x 7 mitch users  0 2010-02-10 11:04 ..
lrwx------ 1 mitch users 64 2010-02-10 11:04 0 -> /dev/pts/2
lrwx------ 1 mitch users 64 2010-02-10 11:04 1 -> /dev/pts/2
lrwx------ 1 mitch users 64 2010-02-10 11:04 2 -> /dev/pts/2
lr-x------ 1 mitch users 64 2010-02-10 11:04 3 -> /proc/29328/fd
Así como en lo anterior se necesita el nombre del archivo que esta enlazado:
stdin="$(ls -l /proc/self/fd/0)"
stdin="${stdin/*-> /}"
Desde ahí se puede probar si esta enlazado al archivo /dev/pts:
if [[ "$stdin" =~ ^/dev/pts/[0-9] ]]; then
echo Terminal
else
echo Pipe: $stdin
fi
Y se prueba de la misma forma:
$ sh ckpipe2.sh
Terminal
$ sh ckpipe2.sh "<"ckpipe2.sh Pipe: .../ckpipe/ckpipe2.sh


Sentencias creadas por Mitch Frazier

No hay comentarios: