Passar comandos para um script que está aguardando uma entrada em uma máquina Linux

0

Estou tentando executar um script de shell dentro do qual eu chamarei outro script e o segundo script aguardará alguns comandos serem fornecidos. Eu usei echo para passar os comandos, mas não funciona. o segundo script continua esperando pela entrada.

script1:

#!/bin/sh
set -x
sh script2.sh
echo ".open Simulation\n"
set +x

mas isso não produz nenhum resultado. continua esperando.

saída:

./script1.sh
+ sh script2
<Nothing appears here>
    
por user188496 06.09.2016 / 15:01

2 respostas

3

Todo processo em sistemas Linux tem uma entrada (stdin) e duas saídas (stdout, stderr) por padrão. Terminais pegam a entrada do teclado e enviam para stdin do shell que eles executam, e pegam stdout e stderr do processo e imprimem na tela.

Quando você executa um comando no shell (em um terminal), ele vincula seu próprio stdin ao do processo, portanto, todas as chaves digitadas são enviadas para o comando. Ele também liga o stdout e o stderr ao seu (o terminal então imprime na tela). A mesma coisa acontece quando você executa um comando dentro de um script, stdin, stdout e stderr são vinculados ao processo pai, que eventualmente se propagam até o terminal.

Além disso, os comandos nos scripts estão bloqueando por padrão. Eles só executarão o próximo comando quando o que estiverem executando terminar.

Considerando isso, vamos analisar seu script (simplificando para as duas linhas de interesse):

sh script2.sh
echo ".open Simulation\n"

O que isto faz é executar sh (que executa script2.sh) e anexa seu stdin ao do script e bloqueia a espera que ele termine. A segunda linha não será executada até que o primeiro processo tenha terminado.

Agora, qualquer coisa que você digitar no shell, por exemplo, .open Simulation\n receberá o envio para sh, que enviará para o script2.sh . Uma vez (se alguma vez) o seu script2.sh terminar, irá sair e o seu script principal irá echo .open Simulation\n para o shell e sairá.

Agora sabemos o que está acontecendo, como podemos corrigi-lo? Bem, você pode substituir a anexação padrão de stdin, stdout e stderr para onde você quiser, incluindo arquivos ou outros processos. Para fazer isso, o shell precisa de utilitários poderosos, redirecionamento de entrada / saída e canais de comando.

O redirecionamento de E / S permite que você redirecione a entrada / saída para qualquer arquivo que você deseja, por exemplo:

echo "contents of a file" > somefile.txt

Isso gravará contents of a file a somefile.txt , redirecionando o stdout do comando echo para somefile.txt . O redirecionamento de entrada funciona da mesma maneira:

cat < somefile.txt

Imprimirá o conteúdo do arquivo na tela redirecionando os gatos stdin para ler somefile.txt (note que este é um exemplo artificial, a maioria das pessoas apenas cat somefile.txt faz com que o cat leia somefile.txt em vez de recebendo o shell para fazer isso.)

A seguir, há os canais de comando, que permitem conectar o stdout de um programa ao stdin de outro. Isso soa como você quer, envia a saída do eco para o stdin do seu script:

echo ".open Simulation" | sh script2.sh

Agora isso funciona bem para uma entrada simples, mas se você tiver mais do que algumas linhas, existe uma maneira mais fácil; Heredocs. Por exemplo, para canalizar várias linhas em seu script, você pode

sh script2.sh <<EOD
.open Simulation
.do something
.end Simulation
EOD

O qual enviará as três linhas (sem incluir o EOD) para o script pronto para o script nos processos. Se você precisar fazer algo mais avançado, você pode usar o redirecionamento de subcomando também, o que permitirá redirecionar a saída de um subshell para o seu programa, aqui com um sleep 1 entre cada linha:

sh script2.sh <(
    echo ".open Simulation"
    sleep 1
    echo ".do something"
    sleep 1
    echo ".end Simulation"
)

Neste exemplo, seu script verá .open Simulation imediatamente e, após um segundo, ele receberá .do something e depois outro segundo .end Simulation antes de stdin ser fechado.

    
por 06.09.2016 / 19:15
2

Tente

echo ".open Simulation" | sh script2.sh

Porque no seu script você acabou de iniciar o script2.sh e está aguardando a entrada. Com o pipe você envia a saída do eco para a entrada padrão de script2.sh

E desculpe, você não precisa inserir '\ n' no echo, porque ele imprime um caractere de nova linha por padrão. (Obrigado)

    
por 06.09.2016 / 15:09