new_bash
다음을 수행할 수 있는 명령을 생성할 수 있습니까 ?
new_bash alias test="ls"
new bash alias new_command="ls"
new_bash test
file1
new_bash new_command
file1
답변1
##Background:
cd $(mktemp -d)
> file1
##Setup state (background bash + pipe)
pipeDir=$(mktemp -d)
mkfifo $pipeDir/p #pipe for communicating with the shell
#start the shell in the background, make it read from the pipe, and disable I/O buffering
stdbuf -i0 -o0 bash < $pipeDir/p &
#open the pipe from the other end on fd 3 (or another fd)
exec 3>$pipeDir/p &&
rm -rf "$pipeDir" #don't need the directory or the physical link to the pipe anymore
##Now you can communicate with the shell
echo ls >&3
#Ouptuts: file1
#This is how you end it all
exec 3>&-
함수는 전역 상태를 유지해야 합니다. 함수에서는 상태가 설정되었는지 확인하고 아직 설정되지 않은 경우 상태를 설정해야 합니다(변수가 존재하는지 확인하여). 일단 설정되거나 상태가 존재하는 경우 echo
해당 인수( "$@"
) &3
또는 파이프를 연 파일 설명자만 사용합니다.
세 가지 기능을 만드는 것이 더 나은 아이디어일 수 있습니다(더 효율적일 것입니다).
init_new_bash
new_bash
end_new_bash
예(더 나은 신호 처리 필요):
#!/bin/sh
#^will work in bash also
init_new_bash(){
set -e #all must succeed
pipeDir=$(mktemp -d)
mkfifo "$pipeDir/p"
stdbuf -i0 -o0 bash < "$pipeDir"/p &
bashPid=$!
exec 3>"$pipeDir/p"
rm -rf "$pipeDir"
set +e
}
new_bash(){ echo "$@" >&3; }
end_new_bash(){ exec 3>&-; wait "$bashPid"; }
##Test run:
init_new_bash && {
new_bash echo hello world
new_bash ls
end_new_bash;}
답변2
당신이 요구하는 것은 단순한 것과 매우 비슷해 보입니다.서브쉘.
예를 들어 명령을 괄호로 묶을 때마다 (ls)
해당 명령은 현재 셸의 하위 프로세스에서 실행됩니다.
귀하의 예를 들어:
(
alias test='ls'
alias new_command='ls'
test
new_command
)
또는 별칭이 서브쉘에 복사되므로
alias test='ls'
alias new_command='ls'
( test ) # one subshell
( new_command ) # another subshell
동일한 서브셸에서 명령을 실행해야 하는 경우:
alias test='ls'
alias new_command='ls'
( test ; new_command ) # same subshell