ProgramingTip

bash를 호출하고 새 셸 내에서 명령을 실행 한 다음 사용자에게 제어권을 다시 제공하는 방법은 무엇입니까?

bestdevel 2020. 11. 18. 09:31
반응형

bash를 호출하고 새 셸 내에서 명령을 실행 한 다음 사용자에게 제어권을 다시 제공하는 방법은 무엇입니까?


... 그럼, 새로운 bash는 인스턴스를 실행하고 사용자에 대한 제어를 실행하고 사용자에 대한 제어 다시 제공하기 위해 노력 하고이 필수 간단하거나 정말 복잡 하나,하지만 난 모든 것이 아무것도 없습니다. .

나는 시도했다 :

$ bash -lic "some_command"

그러나 이것은 some_command새 인스턴스 내에서 실행 다음 닫습니다. 나는 그것이 열려 있기를 바랍니다.

답변에 영향을 미칠 수있는 한 가지 더 자세한 정보 : 작업을 수행이 할 수 있으면 .bashrc별칭으로 사용 하므로 alias구현에 , 대한 보너스 포인트 !


bash --rcfile <(echo '. ~/.bashrc; some_command')

임시 파일 생성을 제거합니다. 다른 사이트에 대한 질문 :


늦은 늦은 답변이지만 똑같은 문제가 Google이 나를이 페이지로 보냈지 만 여기에서 완벽하게 해결했습니다.

내가 말할 수있는 한 bash는 원래 포스터가 원하는 것을 할 수있는 옵션이 없습니다. -c 옵션은 명령이 실행 된 후에 반환됩니다.

깨진 솔루션 : 이것에 대한 가장 간단하고 명백한 시도는 다음과 있습니다.

bash -c 'XXXX ; bash'

이 부분적으로 작동합니다 (추가 하위 쉘 레이어가 있음에도 불구하고). 그러나 상속 된 환경 변수는 상속되지 않습니다. 이제 조치에 대해 조치를 취할 수 있습니다.

더 나은 방법 :이 문제를 해결하는 방법은 동적으로 시작 파일을 만들고 새로운 초기화 파일로 bash를 호출하여 필요한 경우 새 init 파일이 일반 ~ / .bashrc를 호출하는지 확인하는 것입니다.

# Create a temporary file
TMPFILE=$(mktemp)

# Add stuff to the temporary file
echo "source ~/.bashrc" > $TMPFILE
echo "<other commands>" >> $TMPFILE
echo "rm -f $TMPFILE" >> $TMPFILE

# Start the new bash shell 
bash --rcfile $TMPFILE

좋은 점은 즉시 초기화 파일이 사용되는 즉시 삭제되어 정리되지 않습니다.

참고 : / etc / bashrc가 일반적으로 일반 비 로그인 셸의 일부로 호출 확실하지 않습니다. bashrc 아니라 / etc / bashrc를 소스로 사용할 수도 있습니다.


--rcfileBash에 전달 하여 선택한 파일을 읽도록 할 수 있습니다. 대신이 파일을 읽습니다 .bashrc. (그게 문제라면 ~/.bashrc다른 펼쳐에서 출처 를 확인하세요.)

편집 : 따라서 다음과 같이 을 시작하는 기능 은 다음과 같습니다.~/.more.sh

more() { bash --rcfile ~/.more.sh ; }

... 그리고 .more.sh쉘이 시작될 때 실행하려는 명령이 있습니다. (별도의 시작 파일을 피하는 것이 우아하게 생각합니다. 셸이 대화 형이 아니기 때문에 표준 입력을 사용할 수 없지만 임시 위치에있는 문서에서 시작 파일을 만든 다음 읽을 수 있습니다.)


확장을 실행하는 대신 소싱하여 원하는 기능을 얻을 수 있습니다. 예 :

$ 고양이 펼쳐
cmd1
cmd2
$. 펼쳐
$이 시점에서 cmd1 및 cmd2 가이 쉘 내에서 실행되었습니다.

daveraja 의 답변에 따라 여기에 목적을 bash 펼쳐가 있습니다.

C-shell을 사용하는 중이고 다음과 같이 C-shell을 사용 하십시오 / 창을 떠나지 않고 명령을 실행하려는 경우 상황을 고려하십시오.

실행할 명령어 : * .H, * .c 인 파일에서만 재귀 적으로 현재 디렉토리의 '테스트'단어를 정확히 검색

grep -nrs --color -w --include="*.{h,c}" Testing ./

해결 방법 1 : C-shell에서 bash 명령을 실행하십시오.

bash
grep -nrs --color -w --include="*.{h,c}" Testing ./
exit

해결 방법 2 : 의도 한 명령을 텍스트 파일에 작성하고 bash를 사용하여 실행

echo 'grep -nrs --color -w --include="*.{h,c}" Testing ./' > tmp_file.txt
bash tmp_file.txt

해결 방법 3 : bash를 사용하여 같은 줄에서 명령 실행

bash -c 'grep -nrs --color -w --include="*.{h,c}" Testing ./'

해결 방법 4 : sciprt (한 번)를 생성 한 이후의 모든 명령에 사용

alias ebash './execute_command_on_bash.sh'
ebash grep -nrs --color -w --include="*.{h,c}" Testing ./

펼쳐지는 다음과 가변합니다.

#!/bin/bash
# =========================================================================
# References:
# https://stackoverflow.com/a/13343457/5409274
# https://stackoverflow.com/a/26733366/5409274
# https://stackoverflow.com/a/2853811/5409274
# https://stackoverflow.com/a/2853811/5409274
# https://www.linuxquestions.org/questions/other-%2Anix-55/how-can-i-run-a-command-on-another-shell-without-changing-the-current-shell-794580/
# https://www.tldp.org/LDP/abs/html/internalvariables.html
# https://stackoverflow.com/a/4277753/5409274
# =========================================================================

# Enable following line to see the script commands
# getting printing along with their execution. This will help for debugging.
#set -o verbose

E_BADARGS=85

if [ ! -n "$1" ]
then
  echo "Usage: `basename $0` grep -nrs --color -w --include=\"*.{h,c}\" Testing ."
  echo "Usage: `basename $0` find . -name \"*.txt\""
  exit $E_BADARGS
fi  

# Create a temporary file
TMPFILE=$(mktemp)

# Add stuff to the temporary file
#echo "echo Hello World...." >> $TMPFILE

#initialize the variable that will contain the whole argument string
argList=""
#iterate on each argument
for arg in "$@"
do
  #if an argument contains a white space, enclose it in double quotes and append to the list
  #otherwise simply append the argument to the list
  if echo $arg | grep -q " "; then
   argList="$argList \"$arg\""
  else
   argList="$argList $arg"
  fi
done

#remove a possible trailing space at the beginning of the list
argList=$(echo $argList | sed 's/^ *//')

# Echoing the command to be executed to tmp file
echo "$argList" >> $TMPFILE

# Note: This should be your last command
# Important last command which deletes the tmp file
last_command="rm -f $TMPFILE"
echo "$last_command" >> $TMPFILE

#echo "---------------------------------------------"
#echo "TMPFILE is $TMPFILE as follows"
#cat $TMPFILE
#echo "---------------------------------------------"

check_for_last_line=$(tail -n 1 $TMPFILE | grep -o "$last_command")
#echo $check_for_last_line

#if tail -n 1 $TMPFILE | grep -o "$last_command"
if [ "$check_for_last_line" == "$last_command" ]
then
  #echo "Okay..."
  bash $TMPFILE
  exit 0
else
  echo "Something is wrong"
  echo "Last command in your tmp file should be removing itself"
  echo "Aborting the process"
  exit 1
fi

다음 ~/.bashrc과 같은 섹션에 추가 보강.

if [ "$subshell" = 'true' ]
then
    # commands to execute only on a subshell
    date
fi
alias sub='subshell=true bash'

그런 다음 sub.


허용되는 답변은 정말 도움이됩니다! 프로세스 (예 :)를 추가하는 <(COMMAND)대체 방법 일부 쉘 (예 :)에서 지원하지 않습니다 dash.

제 경우에는 Thunar 파일 관리자에서 사용자 지정 작업 (기본적으로 한 줄 셸 스크립트)을 만들어 셸을 시작하고 선택한 Python 가상 환경을 활성화하려고했습니다. 나의 첫 번째 시도는 :

urxvt -e bash --rcfile <(echo ". $HOME/.bashrc; . %f/bin/activate;")

%fThunar에서 처리하는 가상 환경의 경로는 어디 입니까? 명령 줄에서 Thunar를 실행하여 오류가 발생했습니다.

/bin/sh: 1: Syntax error: "(" unexpected

그런 다음 내 sh(본질적으로 dash) 프로세스 대체를 지원하지 않는다는 것을 깨달았습니다 .

내 솔루션은 bash추가 수준의 셸을 희생하면서 프로세스 대체를 해석하기 위해 최상위 수준에서 호출하는 것이 었습니다 .

bash -c 'urxvt -e bash --rcfile <(echo "source $HOME/.bashrc; source %f/bin/activate;")'

또는 here-document를 사용하려고했지만 dash성공하지 못했습니다. 다음과 같은 것 :

echo -e " <<EOF\n. $HOME/.bashrc; . %f/bin/activate;\nEOF\n" | xargs -0 urxvt -e bash --rcfile

추신 : 게시 할 평판이 충분하지 않습니다. 중재자는 댓글로 이동하거나 질문에 도움이되지 않는 경우 삭제 해 주시기 바랍니다.

참고 URL : https://stackoverflow.com/questions/7120426/how-to-invoke-bash-run-commands-inside-the-new-shell-and-then-give-control-bac

반응형