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

… 그럼, 새로운 bash는 인스턴스를 열고 그 안에 몇 가지 명령을 실행하고 사용자에 대한 제어 다시 제공하기 위해 노력하고이 필수 정말 간단하거나 정말 복잡 하나,하지만 난 그것에 대해 아무것도 찾을 수 없습니다 내부에 그 동일한 인스턴스 .

나는 시도했다 :

$ bash -lic "some_command"

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

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



답변

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

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


답변

이것은 늦은 답변이지만 똑같은 문제가 있었고 Google이 저를이 페이지로 보냈으므로 여기에서 완벽하게 문제를 해결 한 방법이 있습니다.

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

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

bash -c 'XXXX ; bash'

이것은 부분적으로 작동합니다 (추가 하위 쉘 레이어가 있음에도 불구하고). 그러나 문제는 하위 셸이 내 보낸 환경 변수를 상속하지만 별칭 및 함수는 상속되지 않는다는 것입니다. 따라서 이것은 어떤 일에는 효과가 있지만 일반적인 해결책은 아닙니다.

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

# 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가 일반적으로 일반 비 로그인 셸의 일부로 호출되는지 확실하지 않습니다. 그렇다면 / etc / bashrc와 ~/.bashrc.


답변

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

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

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

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


답변

스크립트를 실행하는 대신 소싱하여 원하는 기능을 얻을 수 있습니다. 예 :

$ cat 스크립트
cmd1
cmd2
$. 스크립트
$이 시점에서 cmd1 및 cmd2가이 쉘 내에서 실행되었습니다.


답변

다음 ~/.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

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


답변

daveraja 의 답변에 따라 목적을 해결할 bash 스크립트가 있습니다.

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

실행할 명령어 : * .h, * .c 파일에서만 재귀 적으로 현재 디렉토리의 ‘Testing’단어를 정확히 검색

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