Eu uso o servidor Ubuntu 16.04 e desejo usar o utilitário at
na minha sessão atual para fazer algo daqui a 1 minuto (digamos, um echo
), sem fornecer uma data e hora específicas - apenas um minuto antes do horário atual.
Isso falhou:
echo 'hi' | at 1m
A razão que eu escolher at
mais sleep
é porque desvantagens sono sessão atual e é para esse fim mais adequado aos comandos de atraso em outra sessão, em vez do trabalho que nós com a maior parte do tempo. AFAIR, at
não se comporta dessa maneira e não prejudica minha sessão.
Update_1
Pela resposta de Pied Piper, tentei:
(sleep 1m; echo 'hi') &
Estou com um problema com este método: O fluxo "oi" é impresso dentro do meu prompt principal e também adiciona um prompt secundário vazio (_
) logo abaixo do prompt principal que o contém, consulte:
USER@:~# (sleep 1m; echo 'hi') &
[1] 22731
USER@:~# hi
^C
[1]+ Done
Atualização_2
Pela resposta de Peter Corde, tentei:
(sleep 2 && echo -e '\nhi' && kill -WINCH $$ &)
Isso funciona corretamente no Bash 4.4, mas não em algumas versões mais antigas, aparentemente (veja os comentários na resposta). Eu pessoalmente uso o Bash 4.3 em meus próprios ambientes.
Respostas:
Não, é não "impresso na sua
stdin
".Se você pressionasse return, ele não tentaria executar
hi
como um comando. É que o plano de fundo foiecho
impressohi
enquanto o cursor estava após o seu prompt.Talvez você queira imprimir uma nova linha líder , como
(sleep 1m && echo -e '\nhi' &)
. (Ajuste conforme necessário para oecho
seu shell. Ou useprintf
para portabilidade.)Eu coloquei o
&
interior do subshell para "negar" o trabalho em segundo plano, para que você também evite o "ruído" de[1]+ Done
. Com&&
entre os comandos,&
aplica-se a toda a cadeia composto de comando, assim que ele retorna para a direita janela de comandos para longe em vez de esperarsleep
para sair como você deseja obter com(sleep 1; echo ... &)
Aqui está o que acontece (com 1 segundo de atraso):
O Bash não sabe que
echo
imprimiu alguma coisa, por isso não sabe que precisa reimprimir o prompt ou limpar a tela. Você pode fazer isso manualmente comcontrol-L
.Você pode escrever uma função de shell que recebe o bash para reimprimir seu prompt após a
echo
conclusão . Apenas fazerecho "$PS1"
não reproduzirá nenhum caractere já digitado.kill -WINCH $$
no meu sistema, o bash obtém o reimprimir sua linha de prompt sem limpar a tela, deixandohi
uma linha sozinha antes do prompt. O SIGWINCH é enviado automaticamente quando o tamanho do WINdow muda, e a resposta do bash faz o que queremos.Pode funcionar com outras conchas, mas não estou tentando tornar este 100% portátil / POSIX. ( Infelizmente, isso só funciona no bash4.4, não no bash4.3, ou depende de alguma configuração da qual não conheço )
Você pode facilmente agrupar isso em uma função shell que recebe uma mensagem de suspensão e uma mensagem de suspensão.
o bash 4.3 não reimprime seu prompt após o SIGWINCH; portanto, isso não funciona lá. eu tenho
shopt -s checkwinsize
ativei nos dois sistemas, mas ele funciona apenas no sistema Bash 4.4 (Arch Linux).Se não funcionar, você pode tentar o
(sleep 2 && echo -e '\nhi' && echo "$PS1" &)
que "funciona" se a linha de comando estiver vazia. (Ele também ignora a possibilidadePROMPT_COMMAND
definida).Não há uma maneira realmente limpa de fazer com que a saída do terminal se misture com o que você possa estar fazendo no seu terminal mais tarde, quando o timer disparar. Se você estiver no meio de rolar alguma coisa
less
, poderá facilmente perdê-la.Se você estiver procurando algo com resultados interativos, sugiro que você reproduza um arquivo de áudio. por exemplo, com um jogador de linha de comando como
mpv
(belo fork do MPlayer2). Ou escolha um arquivo de vídeo para abrir uma nova janela.Você pode querer
echo
abrir um novo xterm / konsole / gnome-terminal. Use uma opção que mantém o terminal aberto após a saída do comando.fonte
Enter
evento de pressionamento de tecla, logo após o eco aparecer, para que eu retorne automaticamente ao prompt principal do console ?(sleep 2 && echo -e '\nhi' && kill -WINCH $$ &)
.kill -WINCH $$
não atualizar o prompt do shell em execução no terminal. Esse era o objetivo de usá-lo. Pressionar enter enviaria um comando parcialmente digitado, mas WINCH não, como mostrei. Se você não digitou nada, receberá um prompt vazio.rm -rf ~/some/directory
, a opção Enter na hora errada poderia ser executadarm -rf ~/
. (Segurança dica: caminhos de digitação de acabamento e , em seguida, controlar-a e mudançals
pararm -rf
, tão gordo-dedilhado entrar a qualquer momento não vai estragar o seu dia.)(sleep 2 && echo -e '\nhi' && kill -WINCH $$ &)
e, depois que o eco apareceu, recebi um prompt vazio, somente depois de baterEnter
voltei ao prompt principal ... Desculpe se eu entendi errado, sou completamente novo no Bash.screen
sessão (e apenas através do SSH) em um sistema Ubuntu mais antigo, e recebi o comportamento que você descreve.O correto no uso é
at <timespec>
onde<timespec>
está a especificação de tempo. Você também pode usar a-f
opção para especificar o arquivo que contém os comandos a serem executados. Se-f
nenhum redirecionamento for usado, o at lerá os comandos a serem executados a partir do stdin (entrada padrão).No seu exemplo, para executar "algum comando" (eu escolhi "algum comando" para ser "eco oi" no exemplo abaixo) um minuto depois de pressionar enter (agora), o pretendido
<timespec>
a ser usado énow + 1 minute
. Portanto, para obter o resultado desejado com uma solução de uma linha, use o comando abaixo:echo 'echo hi' | at now + 1 minute
Isso deve (e servirá) para executar o
echo hi
comando após um minuto. O problema aqui é que oecho hi
comando será executado pelo comando at em um dummy tty e a saída será enviada para a caixa de correio do usuário (se estiver configurada corretamente - o que requer uma explicação mais extensa sobre como configurar uma caixa de correio no uma máquina unix e não faz parte do escopo desta questão). O ponto principal é que você não poderá ver diretamente o resultadoecho hi
no mesmo terminal em que emitiu o comando. A alternativa mais fácil é redirecioná-lo para "algum arquivo", por exemplo:echo 'echo hi > /tmp/at.out' | at now + 1 minute
No exemplo acima, "some file" é
/tmp/at.out
e o resultado esperado é que o arquivoat.out
em / tmp seja criado após um minuto e contenha o texto 'oi'.Além do
now + 1 minute
exemplo acima, muitas outras especificações de tempo podem ser usadas, mesmo algumas complexas. O comando at é inteligente o suficiente para interpretar legíveis muito humanas, como nos exemplos abaixo:now + 1 day
,13:25
,mid‐night
,noon
, ...Consulte a página de manual do at para obter mais informações sobre as possíveis especificações de horário, pois as variações possíveis são bastante extensas e podem incluir datas, horas relativas ou absolutas, etc.
fonte
at
por padrão, envia a saída por email, mas isso precisa ser configurado corretamente para funcionar.at <timespec>
e a bandeira que você usou e se é compatível com o Ubuntu 16.04 xenial.Execute o
sleep
subshell:Nota: no Linux, você pode dar o argumento para dormir em segundos ou com o sufixo s / m / h / d (por segundos, minutos, horas, dias). No BSD, o argumento deve ser em segundos
fonte
stdin
) e não no meustdout
(como faria com um regularecho
).(sleep 10s; echo 'hi') & 1>
. Agora eu li mais sobre isso.stdin
estdout
. Eles não têm nada a ver com o local onde as coisas aparecem no seu terminal; em vez disso, você deve interpretá-los com relação a um processo específico (basicamente, um programa). A entrada padrão ("stdin") para um processo é uma fonte a partir da qual o processo pode ler dados, e a saída padrão do processo ("stdout") é um destino no qual ele pode gravar dados. Essas fontes e destinos podem ser outros programas, arquivos ou o próprio terminal (as coisas que você digita vão para o stdin e tudo o que vem ao stdout é exibido).Isso falhou porque você está canalizando a saída de
echo "hi"
, que é apenashi
paraat
, masat
espera que sua entrada possa ser executada pelo shell do sistema padrão (geralmente bash, mas às vezes algo diferente dependendo do sistema).Este:
alcançará o que você parece estar tentando fazer. Ele usa uma construção de shell chamada 'aqui document', que geralmente é a maneira aceita de fazer esse tipo de coisa (porque lida com várias linhas melhor do que usar o
echo
comando e não requer a criação de um novo arquivo como você precisaria comcat
) e traduz para o equivalente um pouco mais complicado usandoecho
:Provavelmente vale a pena notar que
at
enviará qualquer saída de comando para o usuário queat
chamou o comando, em vez de direcionar a saída para o terminal como um comando atrasado usandosleep
em um subshell. Em particular, isso significa que, a menos que você tenha feito alguma customização do sistema ou pretenda ler seu spool de correio local, não poderá executar a saída de comandosat
.fonte
syntax error. Last token seen: m Garbled time
. Eu não tenho ideia do porquê. Eu uso o Ubuntu 16.04, Bash 4.0. Talvez você tenha feito isso em outro sistema. Mesmo quando digitoat
sem mais argumentos - ainda recebo o mesmo erro. Mais dados aqui .at 1m
não funciona para um posix compatívelat
. O comando precisaria ser #at now + 1 minute
at
, eu estava assumindo que você tinha uma versão que aceitava essa sintaxe.at 1m
não é POSIX, mas as implementações compatíveis com POSIXat
são livres para interpretá-lo como desejarem, não torna umaat
implementação menos compatível interpretá-lo como o mesmonow + 1 minute
que retornar um erro ou um mês atrás . IOW, é oat 1m
código que não é POSIX.Combine a resposta de Peter Cordes e esta resposta /programming/23125527/how-to-return-to-bash-prompt-after-printing-output-from-backgrounded-function/23125687#23125687
O código abaixo é da última resposta, com uma pequena alteração minha. Compile-o para arquivar a.out (qualquer nome que você quiser)
Em seguida, execute o comando abaixo. (Coloquei a.out em dir / tmp /, pode ser necessário mudar para o seu)
ou
BTW,
kill -WINCH $$
funciona muito bem para mim com o Bash 4.3 no Gentoo.fonte
Com base nas respostas acima, você pode fazer com que o comando incorporado direcione sua saída para o seu terminal, da seguinte maneira:
echo "echo hi >$(tty); kill -WINCH $$" | at now + 1 minute
O
tty
comando retorna o caminho do dispositivo do seu terminal atual, envolvendo-o$(...)
com o bash e executando-o em um sub-shell, e o comando kill envia um sinal para o processo atual que terá o bash reimprimir seu prompt $ PS1.fonte