¿Cómo se puede escribir un script que acepte la entrada de un argumento de nombre de archivo o de stdin?
por ejemplo, podrías usarlo de less
esta manera. uno puede ejecutar less filename
y de manera equivalente cat filename | less
.
¿Hay una manera fácil "fuera de la caja" para hacerlo? ¿o necesito reinventar la rueda y escribir un poco de lógica en el script?
command-line
bash
stdin
gilad hoch
fuente
fuente
Respuestas:
Si el argumento del archivo es el primer argumento de su script, pruebe que hay un argumento (
$1
) y que es un archivo. Otra lectura de entrada de stdin -Entonces su script podría contener algo como esto:
por ejemplo, puedes llamar al script como
o
Editar Alguna explicación del guión:
[ $# -ge 1 -a -f "$1" ]
- Si al menos un argumento de línea de comando ($# -ge 1
) Y (-a operador) el primer argumento es un archivo (-f prueba si "$ 1" es un archivo), entonces el resultado de la prueba es verdadero.&&
es el operador lógico AND del shell. Si la prueba es verdadera, entonces asigneinput="$1"
ycat $input
generará el archivo.||
es el operador lógico de shell OR. Si la prueba es falsa, se analizan los siguientes comandos||
. la entrada se asigna a "-". El comando secat -
lee desde el teclado.Resumiendo, si se proporciona el argumento del script y es un archivo, entonces la entrada variable se asigna al nombre del archivo. Si no hay un argumento válido, cat lee desde el teclado.
fuente
&& input="$1" || input="-"
Qué hace y por qué está fuera deltest
operador?$@
)?read
lee de la entrada estándar. Redirigirlo desde file (./script <someinput
) o a través de pipe (dosomething | ./script
) no hará que funcione de manera diferente.Todo lo que tiene que hacer es recorrer todas las líneas de entrada (y no difiere de iterar sobre las líneas del archivo).
(código de muestra, procesa solo una línea)
Se hará eco de la primera línea de su entrada estándar (ya sea a través
<
o|
).fuente
No mencionas qué shell planeas usar, así que supongo que bash, aunque estas son cosas bastante estándar en todos los shells.
Argumentos de archivo
Se puede acceder a los argumentos a través de las variables
$1
-$n
($0
devuelve el comando utilizado para ejecutar el programa). Digamos que tengo un script que solocat
muestra un número de archivos con un delimitador entre ellos:En este caso, estamos pasando un nombre de archivo a cat. Sin embargo, si desea transformar los datos en el archivo (sin escribirlo y reescribirlo explícitamente), también puede almacenar el contenido del archivo en una variable:
Leer de stdin
En cuanto a la lectura de stdin, la mayoría de los shells tienen un estándar bastante
read
integrado, aunque hay diferencias en cómo se especifican las indicaciones (como mínimo).La página de manual de Bash Builtins tiene una explicación bastante concisa
read
, pero prefiero la página de Bash Hackers .Simplemente:
Variables Múltiples
Para establecer múltiples variables, solo proporcione múltiples nombres de parámetros para
read
:read
luego colocará una palabra de stdin en cada variable, volcando todas las palabras restantes en la última variable.Si se ingresan menos palabras que variables, las variables sobrantes estarán vacías (incluso si se configuraron previamente):
Avisos
Utilizo
-p
flag a menudo para un aviso:Nota: ZSH y KSH (y quizás otros) usan una sintaxis diferente para las indicaciones:
Valores predeterminados
Esto no es realmente un
read
truco, pero lo uso mucho junto conread
. Por ejemplo:Básicamente, si la variable (respuesta) existe, devuélvala, pero si está vacía, devuelva el siguiente parámetro ("N").
fuente
La forma más simple es redirigir stdin usted mismo:
O si prefiere la forma más concisa:
Ahora el resto de su script puede leer simplemente desde stdin. Por supuesto, puede hacerlo de manera similar con un análisis de opciones más avanzado en lugar de codificar la posición del nombre de archivo como
"$1"
.fuente
exec
intentaremos ejecutar el argumento como un comando que no es lo que queremos aquí.if [ "$1" ] ; then exec < "$1" ; fi
un script de prueba y muestra un mensaje de error porque el comando es desconocido. Lo mismo con la forma concisa.usa (o encadena) algo más que ya se comporta de esta manera, y usa
"$@"
Digamos que quiero escribir una herramienta que reemplace las ejecuciones de espacios en el texto con pestañas
tr
es la forma más obvia de hacer esto, pero solo acepta stdin, por lo que tenemos que encadenarcat
:para un ejemplo donde la herramienta que se usa ya se comporta de esta manera, podríamos reimplementar esto con
sed
:fuente
También puedes hacer:
Para más trucos de sustitución de parámetros en Bash, mira esto .
fuente
uglifyjs < /dev/stdin
y funciona de maravilla!También puede mantenerlo simple y usar este código
Cuando crea un archivo de script pass_it_on.sh con este código,
Tu puedes correr
y todo el contenido de stdin simplemente se arrojará a la pantalla.
Alternativamente, use este código para mantener una copia de stdin en un archivo y luego arrojarlo a la pantalla.
y aquí hay otro ejemplo, quizás más legible, explicado aquí:
http://mockingeye.com/blog/2013/01/22/reading-everything-stdin-in-a-bash-script/
Que te diviertas.
RaamEE
fuente
La forma más simple y compatible con POSIX es:
que es equivalente a
${1:--}
.Luego lea el archivo como de costumbre:
fuente