Invocar um comando / script desconectado do terminal de controle?

9

Estou investigando o comportamento de um script que normalmente é executado como um processo automatizado (por exemplo, cron, Jenkins). O script pode (eventualmente) chamar comandos que se comportam de maneira diferente (buscando a entrada do usuário) quando executados de maneira interativa; por exemplo, patchperguntará o que fazer com um patch invertido e svnsolicitará senhas, mas preciso ver o que acontece quando elas são executadas de maneira não interativa.

Convencer patchque não é interativo é bastante fácil; Eu só preciso redirecionar stdoutpara ser um não-tty:

$ </dev/null > >(cat) /path/to/myscript --args

No entanto, svnserá conectado ao terminal de controle, se existir; editar os scripts para passar --non-interactivenão é realmente uma opção, pois isso vem de vários níveis e seria difícil ter certeza de que encontrei todas as chamadas.

Existe uma maneira de chamar um script / comando de maneira não interativa, sem um terminal de controle (para que /dev/ttyisso não exista)? Eu preferiria que o stdout / stderr ainda vá para o meu terminal.

(Encontrei a pergunta Executar script em um shell não interativo? Mas as respostas discutem as diferenças entre o cron e o ambiente do usuário; já eliminei todas as diferenças, exceto a não interatividade.)

ecatmur
fonte

Respostas:

13

Você precisa iniciar outra sessão não conectada a um terminal, por exemplo:

$ setsid sh -c 'tty; ps -jp "$$"; echo test' < /dev/null > log 2>&1
$ cat log
not a tty
  PID  PGID   SID TTY          TIME CMD
19506 19506 19506 ?        00:00:00 sh
test

Veja também o start-stop-daemoncomando encontrado em algumas distribuições Linux. Há também um daemoncomando.

Stéphane Chazelas
fonte
O que essa saída significa? Parece muito enigmático.
techtonik anatoly
2
@anatolytechtonik as partes importantes "não são um tty", que é a saída para ttyconfirmar que não há terminal no stdin, e o "?" na coluna TTY de pssaída que confirma que não há controle tty para o shprocesso (e qualquer coisa em execução sob ele).
precisa saber é o seguinte
Para executar o comando como qualquer outro comando, use setsid -w. Exemplo: setsid -w sh -c 'tty < /dev/tty'gives sh: 1: cannot open /dev/tty: No such device or address(Nota: /dev/ttyé o seu controle tty). Sem -wsetsid executa o processo em paralelo / em segundo plano.
Tino
0

Você provavelmente desejará criar um script esperado. Exemplo com SVN:

/programming/609445/using-expect-to-login-into-svn

Bratchley
fonte
Isso não funciona; expect executa comandos interativamente.
21813 ecatmur
Interativamente em que sentido? No sentido de que requer entrada do usuário? Se é isso que você quer dizer, não haveria muito sentido em esperar nesse caso. Um exemplo para o qual uso é no Solaris, o comando passwd não possui a opção --stdin, por isso tenho um cronjob configurado que executa um script de expectativa que envolve o passwd para fornecer uma senha aleatória para uma conta. Nenhuma interação humana é necessária. Entendo que esse é o requisito do usuário. Eu poderia ter entendido mal.
Bratchley
Na verdade, quanto mais releio isso, mais percebo que entendi mal o que você estava procurando. Desculpas.
Bratchley
0

Às vezes, você precisa manter o stdin aberto (não receber eof no stdin) (por exemplo, esperar). Nesse caso, altere / dev / null para / dev / zero.

setsid sh -c 'make test' </dev/zero >log 2>&1
Roger
fonte