evaluación utilizada con comando canalizado

evaluación utilizada con comando canalizado

Tengo file.txt con el comando almacenado en una línea (este comando es válido cuando se ejecuta en la consola) y quiero ejecutarlo en una línea con sh como

cat file.txt | eval

¿Qué está faltando? ¿Algún consejo profesional?

¿Y si tengo un archivo con muchos comandos (uno para cada línea) y quiero ejecutar solo un comando (una línea completa)? mi primera idea es:

head -n5 | tail -n1 | eval

Respuesta1

evalno lee su cadena de comando desde stdin.

eval "$(cat file.txt)"
# or easier, in ksh/bash/zsh
eval "$(<file.txt)"
# usually you cannot be sure that a command ends at the end of line 5
eval "$(head -n 5 file.txt)"

En lugar de, puede evalusar estándar .o bash// si los comandos están en un archivo de todos modos:zshksh source

source ./file

(tenga en cuenta que es importante agregar eso ./. De lo contrario, sourcebusque fileen $PATHantes de considerar fileen el directorio actual. Si está en modo POSIX, bashni siquiera considerará fileen el directorio actual, incluso si no se encuentra en $PATH).

Por supuesto, eso no funciona al elegir una parte del archivo. Eso podría hacerse mediante:

head -n 5 file.txt >commands.tmp
source ./commands.tmp

O (con ksh93, zsh, bash):

source <(head -n 5 file.txt)

Respuesta2

entonces... una solución a su pregunta es 100% posible y (en el contexto de make) importante.

Me encontré con esto con un archivo MAKE y, dada la dificultad de anidar comandos bash en un archivo MAKE que ya utiliza $(...)para llamar variables, es bueno poder hacer exactamente lo que estás preguntando.

En lugar de usar eval, simplemente use el comando del sistema awko :perl

// command_list.sh:
echo "1"
echo "2"
echo "3"

// command line prompt:
$: cat command_list.sh | awk '{system($0)}'
1
2 
3

Y construcción de comandos:

// a readable version--rather than building up an awk miniprogram, 
// split into logical blocks:

$: cat inputs.txt | awk '{print "building "$1" command "$2" here "}' | awk '{system($0)}' 

Respuesta3

Técnicamente, es imposible evaluar algo dentro de su entorno actual si desea leerlo desde una tubería, ya que cada comando en la tubería se ejecuta como un proceso separado.

Sin embargo, dependiendo de lo que intentes lograr, es posible que eso no importe. En cualquier caso, aquí se ejecuta evalel contenido de una tubería:

❯ echo echo hi | eval "$(cat -)"
hi

He aquí un ejemplo de la captura. Algo como lo siguiente no se imprimirá 1:

❯ echo a=1 | eval "$(cat -)"; echo $a

Tendríamos que hacer lo siguiente en su lugar:

❯ echo a=1 | { eval "$(cat -)"; echo $a; }
1

Respuesta4

Si no estás decidido a utilizar eval, utiliza sh:

cat file.txt | sh

Sí, se ejecutará en una instancia sh separada, pero ese hecho está autodocumentado.

Y también hay while read:

cat file.txt | while read cmd; do eval $cmd; done

Para ejecutar el comando en la quinta línea del archivo.txt:

sed -n 5p file.txt | sh

(Me doy cuenta de que esta es una vieja pregunta).

información relacionada