( exec sh -i 3<<SCRIPT 4<&0 <&3 ⏎
echo "do this thing"
echo "do that thing"
exec 3>&- <&4
SCRIPT
)
É melhor fazer isso a partir de um script, embora com exec $0.Ou, se um desses descritores de arquivo direcionar para um dispositivo de terminal que não está sendo usado no momento, ajudará - você deve se lembrar, outros processos também querem verificar esse terminal.
E, a propósito, se seu objetivo é, como presumo, preservar o ambiente do script após executá-lo, você provavelmente será muito melhor atendido:
. ./script
O shell .dote bash's sourcenão são o mesmo - o shell .doté POSIX especificado como um shell especial embutido e, portanto, está o mais próximo possível de ser garantido, embora isso não seja de forma alguma uma garantia de que estará lá ...
Embora o acima deve fazer o que você espera com pouco problema. Por exemplo, você pode:
( exec sh -i 3<<SCRIPT 4<&0 <&3 ⏎
echo "do this thing"
echo "do that thing"
$(cat /path/to/script)
exec 3>&- <&4
SCRIPT
)
O shell executará seu script e o levará ao prompt interativo - desde que você evite exito shell do script, ou seja, faça um background de seu processo - que vinculará sua E / S ao/dev/null.
DEMO:
% printf 'echo "%s"\n' "These lines will print out as echo" \
"statements run from my interactive shell." \
"This will occur before I'm given the prompt." >|/tmp/script
% ( exec sh -i 3<<SCRIPT 4<&0 <&3
echo "do this thing"
echo "do that thing"
$(cat /tmp/script)
exec 3>&- <&4
SCRIPT
)
sh-4.3$ echo "do this thing"
do this thing
sh-4.3$ echo "do that thing"
do that thing
sh-4.3$ echo "These lines will print out as echo"
These lines will print out as echo
sh-4.3$ echo "statements run from my interactive shell."
statements run from my interactive shell.
sh-4.3$ echo "This will occur before I'm given the prompt."
This will occur before I'm given the prompt.
sh-4.3$ exec 3>&- <&4
sh-4.3$
MUITOS JOBS
É minha opinião que você deve se familiarizar um pouco mais com as opções internas de gerenciamento de tarefas do shell. O @Kiwy e o @jillagre já abordaram isso em suas respostas, mas isso pode exigir mais detalhes. E eu já mencionei um shell especial específico do POSIX embutido, mas set, jobs, fg,e bgsão mais alguns, e, como outra resposta demonstra trape killsão mais dois ainda.
Se você ainda não está recebendo notificações instantâneas sobre o status de processos em segundo plano em execução simultaneamente, é porque suas opções atuais de shell estão definidas no padrão especificado pelo POSIX -m, mas você pode obtê-las de forma assíncrona set -b:
% man set
−b This option shall be supported if the implementation supports the
User Portability Utilities option. It shall cause the shell to
notify the user asynchronously of background job completions. The
following message is written to standard error:
"[%d]%c %s%s\n", <job-number>, <current>, <status>, <job-name>
where the fields shall be as follows:
<current> The character '+' identifies the job that would be
used as a default for the fg or bg utilities; this
job can also be specified using the job_id "%+" or
"%%". The character '−' identifies the job that
would become the default if the current default job
were to exit; this job can also be specified using
the job_id "%−". For other jobs, this field is a
<space>. At most one job can be identified with '+'
and at most one job can be identified with '−'. If
there is any suspended job, then the current job
shall be a suspended job. If there are at least two
suspended jobs, then the previous job also shall be a
−m This option shall be supported if the implementation supports the
User Portability Utilities option. All jobs shall be run in their
own process groups. Immediately before the shell issues a prompt
after completion of the background job, a message reporting the
exit status of the background job shall be written to standard
error. If a foreground job stops, the shell shall write a message
to standard error to that effect, formatted as described by the
jobs utility. In addition, if a job changes status other than
exiting (for example, if it stops for input or output or is
stopped by a SIGSTOP signal), the shell shall write a similar
message immediately prior to writing the next prompt. This option
is enabled by default for interactive shells.
Uma característica muito fundamental dos sistemas baseados em Unix é o método de manipulação de processos signals. Certa vez, li um artigo esclarecedor sobre o assunto que compara esse processo à descrição de Douglas Adams do planeta NowWhat:
"No Guia do Mochileiro das Galáxias, Douglas Adams menciona um planeta extremamente monótono, habitado por um grupo de humanos deprimidos e uma certa raça de animais com dentes afiados que se comunicam com os humanos mordendo-os com muita força nas coxas. Isso é impressionante. semelhante ao UNIX, no qual o kernel se comunica com os processos enviando sinais paralisantes ou mortais a eles. Os processos podem interceptar alguns dos sinais e tentar se adaptar à situação, mas a maioria não. "
Isso está se referindo kill signals.
% kill -l
> HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH POLL PWR SYS
Pelo menos para mim, a citação acima respondeu a muitas perguntas. Por exemplo, sempre achei muito estranho e nada intuitivo que, se quisesse monitorar um ddprocesso, fosse necessário kill. Depois de ler isso, fez sentido.
Eu diria que a maioria deles não tenta se adaptar por um bom motivo - pode ser um aborrecimento muito maior do que um benefício ter vários processos enviando spam ao seu terminal com qualquer informação que seus desenvolvedores pensassem que poderia ser importante para você .
Dependendo da configuração do terminal (com a qual você pode verificar stty -a) , CTRL+Zé provável que seja encaminhado a SIGTSTPpara o atual líder do grupo de processos em primeiro plano, que provavelmente é seu shell e que também deve ser configurado por padrão para trapesse sinal e suspender seu último comando. Novamente, como mostram as respostas de @jillagre e @Kiwy juntas, não há como impedir que você adapte essa funcionalidade ao seu objetivo, como preferir.
SCREEN JOBS
Portanto, para tirar proveito desses recursos, é esperado que você os entenda primeiro e personalize seu manuseio de acordo com suas próprias necessidades. Por exemplo, eu encontrei este screenrc no Github que inclui screenligações de teclas para SIGTSTP:
# hitting 'C-z C-z' will run Ctrl+Z (SIGTSTP, suspend as usual)
bind ^Z stuff ^Z
# hitting 'C-z z' will suspend the screen client
bind z suspend
Isso tornaria simples suspender um processo em execução como um screenprocesso filho ou o screenpróprio processo filho, como você desejasse.
E imediatamente depois:
% fg
OU:
% bg
Primeiro ou segundo plano o processo como você preferir. O jobsbuilt-in pode fornecer uma lista deles a qualquer momento. A adição do -loperando incluirá detalhes do pid.