( exec sh -i 3<<SCRIPT 4<&0 <&3 ⏎
echo "do this thing"
echo "do that thing"
exec 3>&- <&4
SCRIPT
)
Isso é melhor feito a partir de um script com exec $0.
. Ou se um desses descritores de arquivo direcionar para um dispositivo de terminal que não está sendo usado, ele ajudará - você precisa lembrar, outros processos querem verificar esse terminal, também.
E, a propósito, se seu objetivo for preservar o ambiente do script depois de executá-lo, provavelmente você será muito mais bem servido com:
. ./script
Os .dot
e bash's source
do shell não são um e o mesmo - o .dot
do shell é POSIX especificado como um shell especial integrado e, portanto, está tão próximo de ser garantido quanto possível, embora isso não seja feito significa 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 retornará você ao prompt interativo - contanto que você evite exit
ing o shell do seu script, ou seja, o fundo do processo - que vinculará sua i / o a /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 ficar um pouco mais familiarizado com as opções de gerenciamento de tarefas embutidas do shell. @Kiwy e @jillagre já mencionaram isso em suas respostas, mas isso pode exigir mais detalhes. E eu já mencionei um shell especial POSIX especificado embutido, mas set, jobs, fg,
e bg
são mais alguns, e, como outra resposta demonstra trap
e kill
são mais dois ainda.
Se você ainda não está recebendo notificações instantâneas sobre o status de execução simultânea de processos em segundo plano, é porque suas opções de shell atuais estão definidas para o padrão de -m
especificado pelo POSIX, mas você pode obtê-las de forma assíncrona com set -b
em vez disso:
% 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 importante dos sistemas baseados em Unix é o método de processamento do processo signals
. Uma vez li um artigo esclarecedor sobre o assunto que compara este processo à descrição de Douglas Adams sobre o planeta NowWhat :
"In The Hitchhiker's Guide to the Galaxy, Douglas Adams mentions an extremely dull planet, inhabited by a bunch of depressed humans and a certain breed of animals with sharp teeth which communicate with the humans by biting them very hard in the thighs. This is strikingly similar to UNIX, in which the kernel communicates with processes by sending paralyzing or deadly signals to them. Processes may intercept some of the signals, and try to adapt to the situation, but most of them don't."
Isto está se referindo a 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, eu sempre considerei muito estranho e nada intuitivo que, se eu quisesse monitorar um processo dd
, eu tivesse que kill
dele. Depois de ler isso fazia sentido.
Eu diria que a maioria deles não tenta se adaptar por um bom motivo - pode ser um aborrecimento muito maior do que seria um bocado ter um monte de processos spamming seu terminal com qualquer informações que seus desenvolvedores acharam que poderiam ter sido importantes para você.
Dependendo da sua configuração do terminal (que você pode verificar com stty -a
) , o CTRL+Z
provavelmente está definido para encaminhar um SIGTSTP
para o líder do grupo de processos do primeiro plano atual, o que provavelmente é shell, e que também deve ser configurado por padrão para trap
desse sinal e suspender seu último comando. Novamente, como as respostas de @jillagre e @Kiwy juntas mostram, não há como impedi-lo de adaptar essa funcionalidade ao seu propósito como preferir.
SCREEN JOBS
Portanto, para aproveitar esses recursos, é esperado que você os entenda e personalize o tratamento de acordo com suas próprias necessidades. Por exemplo, acabei de encontrar esta screenrc no Github que inclui screen
key- ligações 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 simplifica a suspensão de um processo em execução como um processo screen
child ou o processo filho screen
como desejado.
E imediatamente depois:
% fg
OR:
% bg
Primeiro ou segundo plano do processo, conforme você preferir. O jobs
integrado pode fornecer uma lista desses a qualquer momento. Adicionar o operando -l
incluirá detalhes do pid.