각 탭 실행을 시작하는 명령을 받아들이는 다중 탭 터미널이 있습니까?

각 탭 실행을 시작하는 명령을 받아들이는 다중 탭 터미널이 있습니까?

내 목표는 다중 터미널 환경을 시작하는 것입니다.

  • 키보드 키를 누르는 것처럼 한 번에 모든 터미널에 쉽게 액세스할 수 있습니다(yakuake 및 guake를 사용하여 이 작업을 수행할 수 있습니다).
  • 항목이 어디에 있는지 알 수 있도록 맞춤 이름이 붙은 탭
  • 미리 실행된 전체 명령으로 멀티탭 터미널을 실행하여 각 탭 터미널에 대한 완전한 설정 환경을 갖출 수 있습니다.

오늘은 무엇을 하나요?
guake를 열었는데 yakuake보다 RAM을 적게 사용합니다.
F5와 같은 키를 누르고 개발을 위한 기본 환경을 시작할 수 있도록 Bash에 일부 키 바인딩이 구성되어 있으므로 여전히 각 특정 터미널에 대해 F5를 눌러야 합니다.
여전히 5개 탭 각각에 특정 명령을 입력해야 합니다.
또한 어떤 특정 명령을 실행할지 알 수 있도록 이전에 이름을 지정했습니다.

연구:

  • 멀티탭 단자 : 야쿠아케, 과케,미스터 xvt.
  • 이름 변경 가능한 탭: guake, yakuake. 하지만 mrxvt에 대한 방법을 찾을 수 없습니다.
  • 우리가 사용할 수 있다는 걸 알아요버스 탭 이름 변경 등 yakuake를 사용하여 많은 작업을 수행할 수 있습니다. guac에 대해 잘 모르겠습니다. mrxvt를 사용하여 탭 이름을 변경하는 방법을 찾을 수 없습니다.

최종 결과를 얻으려면 간접적인 방법(명령줄이 필요하지 않고 qdbus를 통할 수 있음)이면 충분합니다. 몇 가지 스크립트를 준비하면 됩니다.

가장 낮은 RAM(mrxvt)을 사용하는 애플리케이션도 실행 중인 다른 애플리케이션을 처리하는 데 중요하지만 이를 사용하여 목표를 달성할 수 없다면 소용이 없습니다.

답변1

"다중 터미널" 환경을 찾고 있다면 터미널 자체를 찾는 것이 아니라(터미네이터가 좋은 선택입니다) 대신 터미널 멀티플렉서에 대한 경로를 확인하는 것이 좋습니다 tmux.

이를 통해 tmux고급 터미널의 모든 장점을 누릴 수 있을 뿐만 아니라 모든 터미널과 원격 서버에서도 사용할 수 있습니다.

tmux또 다른 장점은 터미널을 닫아도 TMUX 세션이 여전히 존재하고 재개할 수 있으며 모든 vim 파일, o 프로그램 및 ssh 세션이 여전히 실행 중이라는 것입니다.

미리 정의된 TABS(tmux의 창)를 사용하여 여러 터미널을 구성하고 일부 명령을 자동으로 실행하기 위해 tmuxtmuxinator(https://github.com/tmuxinator/tmuxinator) 및 tmuxp(https://tmuxp.git-pull.com/)

tmuxp 예

session_name: 4-pane-split
start_directory: ./ # load session relative to config location (project root).
before_script: ./.tmuxp-before-script.sh
shell_command_before:
  - '[ -f .venv/bin/activate ] && source .venv/bin/activate && reset'
windows:
  - window_name: dev window
    layout: tiled
    shell_command_before:
      - cd ~/ # run as a first command in all panes
    panes:
      - shell_command: # pane no. 1
          - cd /var/log # run multiple commands in this pane
          - ls -al | grep \.log
      - echo second pane # pane no. 2
      - echo third pane # pane no. 3
      - echo forth pane # pane no. 4
  - window_name: docs
    layout: main-horizontal
    options:
      main-pane-height: 35
    start_directory: docs/
    panes:
      - focus: true
      - pane
      - make serve
      - make SPHINXBUILD='poetry run sphinx-build' watch

일부 링크:

답변2

guake 버전 >= 3.8.5-1인 경우 다음이 필요합니다. (
cat >>bashAutoCmdOnStart.sh그리고 이 명령을 ~/.bashrc 끝에 추가합니다.)

#!/bin/bash

strFlBase="/tmp/`basename "$0"`."

if [[ "$1" == "--getExecFileForUID" ]];then
  shift
  echo "Showing id for current term on guake:" >&2
  echo "${strFlBase}$1"
  exit 0
fi

#TODO for yakuake too
if [[ -z "$GUAKE_TAB_UUID" ]];then declare -p GUAKE_TAB_UUID;exit 0;fi

: ${bBashAutoCmdOnStart:=true} #help
if ! $bBashAutoCmdOnStart;then ps;pwd;declare -p bBashAutoCmdOnStart;exit 0;fi

ps;pwd
strFlExec="${strFlBase}$GUAKE_TAB_UUID"
nCount=0
while true;do
  echo -ne "$SECONDS: wating terminal auto cmd ($strFlExec). Hit any key for prompt.\r";
  #TODO test if terminal is interactive, I think `read` is failing when guake loads initially on pc restart
  if read -t 3 -n 1;then break;fi;
  if [[ -f "$strFlExec" ]];then
    echo "EXECUTING file contents '$strFlExec' here:"
    cat "$strFlExec"
    strRunFl="${strFlExec}.Running.${nCount}"
    mv -v "$strFlExec" "$strRunFl"
    #chmod +x "${strFlExec}.Running"
    source "${strRunFl}"
    ps;pwd
    #bash -c "${strFlExec}.Running;ps;pwd;bash"
    ((nCount++))&&:
  fi
done
ps;pwd
bBashAutoCmdOnStart=false bash

예제를 실행하려면: guakeAutoEnv.sh [-x] -ID_CMD workA ls 123 -ID_CMD workB ls 456 789#-x는 (현재 guake 탭 대신) xterm에서 실행하는 것입니다. cat >>guakeAutoEnv.sh

#!/bin/bash

nWId="`wmctrl -l |grep "Guake!" |awk '{print $1}'`";declare -p nWId

: ${bUseBashAutoCmdMode:=false}
if ! qdbus org.guake3.RemoteControl /org/guake3/RemoteControl |grep execute_command_by_uuid;then
  #echoc --alert "@{-n}execute_command_by_uuid was @nremoved@{-n}, therefore this script wont work that way anymore :(";
  bUseBashAutoCmdMode=true
fi

if [[ -z "${1-}" ]] || [[ "${1}" == --help ]];then
  #help Usage ex.: [-x] -ID_CMD coolName ls 123 -ID_CMD funnyName ls 456 789
  egrep "[#]help" $0 |sed -r -e 's"^[[:space:]]*""' -e 's"[[:space:]]*$""' >/dev/stderr
  exit 0
fi

export bUsingXtermToRun=false;
if [[ "${1-}" == "-x" ]];then 
  bUsingXtermToRun=true;
  shift&&:;
  (xterm -e $0 "$@"&disown) #w/o -x now
  exit
fi

set -Eeu

# depends on
while ! pgrep -fa "`which guake`";do echo " >>>>> WARN:WaitingGuakeStart";sleep 3;done #this line checks for a running guake
while ! qdbus org.guake3.RemoteControl;do echo " >>>>> WARN:WaitingGuakeDBus";sleep 3;done #this line checks for a listening guake

function FUNCexecEcho() {
  echo " EXEC: $@" >/dev/stderr
  "$@"
};export -f FUNCexecEcho

function FUNCgrc() {
  FUNCexecEcho qdbus org.guake3.RemoteControl /org/guake3/RemoteControl org.guake3.RemoteControl."$@"
}

# read parameters
acmd=()
astrIdList=()
astrOptList=()
iIdIndex=0
function FUNCchkCmd() { if [[ "${1:0:7}" == "-ID_CMD" ]];then return 0;else return 1;fi; } # <"$1">
while ! ${1+false};do
  if FUNCchkCmd "${1}";then
    echo " >>> NEW ID_CMD iIdIndex=$iIdIndex:"
    astrOptList+=("${1#-ID_CMD}");shift
    astrIdList+=("$1");shift;
    continue;
  fi
  
  acmd+=("$1");shift
  if ${1+false} || FUNCchkCmd "${1}";then
    echo "astrOptList[$iIdIndex]='${astrOptList[$iIdIndex]}'"
    echo "astrIdList[$iIdIndex]='${astrIdList[$iIdIndex]}'"
    eval 'aIdCmd'${iIdIndex}'=("${acmd[@]}")';declare -p aIdCmd${iIdIndex}
    ((iIdIndex++))&&:
    acmd=()
  fi
done
declare -p astrIdList

# detect existing tabs
iTabCount="`FUNCgrc get_tab_count`"
iCurrentTabIndex="`FUNCgrc get_selected_tab`"
strCurrentTabUUID="`FUNCgrc get_selected_uuidtab`"
astrTabUUIDList=()
astrTabNameList=()
for((i=0;i<iTabCount;i++));do
  echo
  declare -p i
  strTabName="`FUNCgrc get_tab_name $i`";declare -p strTabName
  if((i==iCurrentTabIndex));then echo " CURRENT TAB";fi
  
  FUNCgrc select_tab $i
  astrTabUUIDList+=("`FUNCgrc get_selected_uuidtab`")
  astrTabNameList+=("`FUNCgrc get_tab_name $i`")
done
FUNCgrc select_tab $iCurrentTabIndex # this first is reached fast so the user has not to wait a long time
: ${bGoBackToInitialTab:=false} #help will re-select select the tab this script was run on at the end

declare -p astrTabUUIDList |tr '[' '\n'
declare -p astrTabNameList |tr '[' '\n'

function FUNCrunCmd() {
  strOpts="$1";shift
  strTabName="$1";shift
  strTabUUID="$1";shift
  iIdCmd="$1";shift

  aOptList=();if [[ -n "$strOpts" ]];then aOptList+=(`echo "$strOpts" |sed -r 's@(.)@\1 @g'`);fi
  
  echo
  echo " TabName: ${strTabName}, CMDOPTION(s): ${aOptList[@]} "
  
  eval 'acmdRun=("${aIdCmd'${iIdCmd}'[@]}")';declare -p acmdRun
  
  bSubShell=true
  bForceCurrentTab=false
  bRetryOnError=false
  for strOpt in "${aOptList[@]}";do
    case "$strOpt" in
      n)bSubShell=false;; #help CMDOPTION: The default is to run using `bash -c '$cmd'`. To disable this, use like ex.: `-ID_CMDn cd ComePathToApplyAtCurrentShell`
      c)bForceCurrentTab=true;if ! $bUsingXtermToRun;then echo " >>>>> WARNING <<<<< 'c' CMDOPTION is more reliable using '-x' option!!!";fi;; #help CMDOPTION: The tab name will only be ignored (but only if it does not exist ex.: "IgnoredCurrentTabName") and the current tab running this script will be used. This option is more reliable with -x option.
      r)bRetryOnError=true;; #help CMDOPTION: if the command fails returning any error, it will retry running it after 3s.
      *)$0 --help;echo "ERROR: invalid option '$strOpt' for strTabName='${strTabName}' and command: ${acmdRun[*]}";exit 1;;
    esac
  done
  
  # create and run a tmp script
  strFl="`tempfile`";chmod +x "$strFl"
  echo '#!/bin/bash
    cat $0; # review the command
    '"$(declare -p acmdRun)"'; # '"${acmdRun[@]}"'
    echo >'"${strFl}.started"'
    if '$bRetryOnError';then
      while ! "${acmdRun[@]}";do echo "failed error $?";sleep 3;done
    else
      "${acmdRun[@]}";
    fi
    ' >"$strFl"
    
  while true;do
    bForceIgnoreStart=false
    
    if $bUseBashAutoCmdMode && $bSubShell;then
      bSubShell=false
      echo "WARN: disabling subshell mode to let bUseBashAutoCmdMode work for now." >&2
    fi
    
    if $bSubShell;then
      strCmd="bash -c ${strFl}"
    else
      # can the command passed thru qdbus param cause some problem if it is too complex? `bash -c` above is to prevent that.
      strCmd="`declare -p acmdRun`;"'"${acmdRun[@]}"'
      bForceIgnoreStart=true
    fi
    
    if $bUseBashAutoCmdMode;then
      #echoc --alert "@{-n}execute_command_by_uuid was @nremoved@{-n}, therefore this script wont work that way anymore :(";
      #exit 1
      strExecFile="`bashAutoCmdOnStart.sh --getExecFileForUID "$strTabUUID"`"
      echo "$strCmd" >>"$strExecFile"
      while [[ -f "$strExecFile" ]];do
        #echo "INFO: Waiting '$strExecFile' be consumed..."
        read -p "(`date`)INFO: Waiting '$strExecFile' be consumed... skip waiting? (y/...)`echo -ne "\r"`" -t 1 -n 1 strResp&&:;if [[ "$strResp" == "y" ]];then break;fi
        sleep 1
      done
    else
      # this is for old guake version
      if [[ "$strTabUUID" == "USE_CURRENT_TAB" ]];then
        FUNCgrc execute_command "$strCmd"
      else
        FUNCgrc execute_command_by_uuid "$strTabUUID" "$strCmd"
      fi
    fi
    
    sleep 1 #wait it start running
    
    : ${bWaitStart:=true} #help wait the command start running before sending the next one
    bForceRetry=false
    bKeepTmpExecFile=false
    bReallyWaitStart=$bWaitStart;if $bForceIgnoreStart;then bReallyWaitStart=false;fi
    if $bReallyWaitStart;then
      if $bForceCurrentTab || [[ "$strCurrentTabUUID" == "$strTabUUID" ]];then
        echo " >>>>>>>>>>>> "
        echo " >>>>> ATTENTION!!! this command '${acmdRun[*]}' was requested to be run on this current tab [$iCurrentTabIndex]'${strTabName}'($strCurrentTabUUID), so this script will not wait for the command to start and the related temporary exec file '${strFl}' will be kept."
        echo " >>>>>>>>>>>> "
        bKeepTmpExecFile=true
      else
        nW=0
        while [[ ! -f "${strFl}.started" ]];do
          echo " >>>>>>>>>>>> "
          echo "     > `date`: Waiting ($((nW++))) the command start running:"
          echo "     > TAB: strTabName='${strTabName}',strTabUUID='$strTabUUID'"
          echo "     > CMD$iIdCmd: '${acmdRun[*]}'"
          echo "     > It may fail if there was some command typed and not executed yet there."
          echo "     > It may fail if there happened an input request there."
          echo "     > So you better check if no problem happened!"
          echo "     > But if no problem happened and you force a retry, it will be buffered and will execute again."
          echo "     > Force retry run now? (y/...)"
          echo " >>>>>>>>>>>> "
          strResp="$(read -t 3 -n 1 strResp;echo "$strResp")";echo #the script was stopping here... why did I have to subshell?
          if [[ "$strResp" == "y" ]];then echo " >>>>> Retrying";bForceRetry=true;break;fi
        done
      fi
    fi
    
    if ! $bForceRetry;then break;fi
  done
  
  : ${bRmTmpFiles:=false} #help delete temporary files
  if $bRmTmpFiles && ! $bKeepTmpExecFile;then rm -v "${strFl}" "${strFl}.started";fi
};export -f FUNCrunCmd

# run the commands
for iId in "${!astrIdList[@]}";do
  declare -p iId
  echo " Id: ${astrIdList[iId]}"
  
  bFound=false
  
  for iTab in "${!astrTabNameList[@]}";do
    strOpt="${astrOptList[iId]}"
    bRunOnThisTab=false
    if [[ "${astrTabNameList[iTab]}" == "${astrIdList[iId]}" ]];then bRunOnThisTab=true;fi
    if ((iTab==iCurrentTabIndex)) && [[ "$strOpt" =~ .*c.* ]];then bRunOnThisTab=true;fi
    if $bRunOnThisTab;then
      FUNCrunCmd "$strOpt" "${astrIdList[iId]}" "${astrTabUUIDList[iTab]}" $iId
      bFound=true
      break
    fi
  done
  
  : ${bAddTab:=true} #help if it doesnt exist yet
  if ! $bFound;then
    if $bAddTab;then
      FUNCgrc add_tab "$HOME"
      FUNCgrc rename_current_tab "${astrIdList[iId]}"
      astrTabNameList+=("${astrIdList[iId]}")
      astrTabUUIDList+=("`FUNCgrc get_selected_uuidtab`")
      FUNCrunCmd "${astrOptList[iId]}" "${astrIdList[iId]}" "USE_CURRENT_TAB" $iId
    else
      echo " >>>>>>>>>>>> "
      echo " >>>>> WARNING: could not find a matching tab name for '${astrIdList[iId]}'"
      echo " >>>>>>>>>>>> "
    fi
  fi
done #for iId in "${!astrIdList[@]}";do

if $bGoBackToInitialTab;then FUNCgrc select_tab $iCurrentTabIndex;fi

관련 정보