나는 사용자 정의 그놈 터미널 프로필을 작성 중이며 내가 선택한 키를 사용하여 프로필을 중지하고 싶습니다. 키를 누른 후 그 당시의 모든 명령을 완료하고 su를 시작하려는 의도입니다. 명령에 &를 추가하려고 시도했지만 작동하지 않습니다. 몇 가지 정보를 첨부합니다:
내 코드:
su --command 'read -n 1 -s key; if [ "$key" == "g" ]; then su; fi;'
echo -n "W"
sleep 0.09
echo -n "e"
sleep 0.09
echo -n "l"
sleep 0.09
echo -n "c"
sleep 0.09
echo -n "o"
sleep 0.09
echo -n "m"
sleep 0.09
echo -n "e"
sleep 0.09
예상되는 결과:
[문자는 다음까지 올바르게 에코됩니다...]
[키를 눌렀다]
Welcome
root@myuser:~#
답변1
비슷한 질문에 가장 가까운 것은 다음과 같습니다.
먼저 inputproc이라는 스크립트를 만듭니다.
read -n1
그런 다음 mainscript라는 스크립트를 만듭니다.
array=(W e l c o m e)
buf=0
while pgrep "inputproc" > /dev/null; do
echo -n ${array[buf]}
((buf++))
sleep 0.09
done
#Insert any commands you want to run afterwards here...
그런 다음 이 명령으로 실행하십시오.
./mainscript & ./inputproc
글쎄, 그것이 바로 당신이 원하는 것입니다. 스크립트만으로는 이를 수행할 수 있는 방법을 찾을 수 없었지만 놀랍게도 터미널 창만으로 이를 수행할 수 있는 방법을 찾았습니다.
명백한 것 외에도 (while 루프를 사용하여 다음을 확인하십시오.입력과정각 echo 명령 앞에 실행하고 배열을 사용하여 필요한 문자를 순서대로 에코합니다. 이는 다음을 실행하여 수행할 수 있습니다.메인 스크립트실행 중 백그라운드에서 실행입력과정리셉션. 결함이 없는 것은 아니지만 원하는 결과에 가장 근접하게 도달할 수 있다고 믿습니다.
답변2
이것은 너무 많은 수준에서 작동하지 않습니다. 주로 bash는 다중 스레드 프로그래밍에 적합하지 않습니다. 그러나 이를 수행할 계획이라면 다음 두 가지를 인식해야 합니다. (1) 키 읽기 "스레드"가 작동하려면 tty에 대한 독점 액세스 권한이 있어야 합니다. (2) 프로세스를 백그라운드에 놓으면 자연스럽게 현재 프로세스의 tty에서 stdin을 복사합니다. (3) 일반적으로 쉘은 이를 감지하고 백그라운드 프로세스를 중지합니다.
포그라운드 프로세스만 터미널을 읽거나 쓸 수 있습니다(사용자가 stty tostop을 사용하여 지정한 경우). 커널의 터미널 드라이버는 터미널에서 읽기를 시도하는(그리고 stty tostop이 적용될 때 쓰기를 시도하는) 백그라운드 프로세스에 SIGTTIN(SIGTTOU) 신호를 보내고 프로세스는 잡히지 않는 한 정지됩니다.
여기서 볼 수 있습니다:
otheus@otheus-VirtualBox ~ $ ( while true; read x; do echo $x; done; ) &
[1] 2841
otheus@otheus-VirtualBox ~ $
[1]+ Stopped ( while true; read x; do
echo $x;
done )
따라서 tty 읽기 프로세스는 전경에 있어야 합니다. "작업"은 백그라운드에서 수행될 수 있지만 먼저 표준 입력을 닫아야 합니다.<&-
"작업자" 프로세스를 중지하려면 해당 프로세스의 pid를 알아야 합니다. 이렇게 하려면 스크립트에서 작업 제어를 활성화해야 합니다(기본적으로 꺼져 있음). set -m
이 작업을 수행. %-
키를 누른 후 시작하고 종료하십시오. 작업자가 종료되면 키 주기도 종료되는지 확인할 수 있습니다. 키 누르기 모니터링 스레드를 수행합니다.
start_worker &
while jobs %- &>/dev/null; do
read -n 1 -s -t 1 key
# test key
if [[ $key == q ]]; then
kill -1 %-
break
fi
fi
wait
while 조건은 작업이 여전히 실행 중이거나 식별되는지 여부를 테스트합니다. 작업이 끝나면 작업은 false를 반환하고 루프가 종료됩니다. 이제 읽기 명령도 1초 후에 시간 초과됩니다. 마지막으로 루프가 종료된 후 작업이 "정리"되었는지 확인할 때까지 기다립니다. (다른 작업을 실행 중인 경우 여기에서 중단됩니다.)
또 다른 점은 달성하려는 작업이 본질적으로 위험하다는 것입니다.루트 액세스와 bash 스크립팅을 혼합하는 것은 위험합니다.. 사용자가 Control-C 또는 Ctl-Z를 누르면 어떤 일이 발생하는지와 같이 여기에서 논의할 몇 가지 주제가 있습니다.
su
마지막으로, 작업자 스레드를 귀하의 예에 있는 스레드와 혼합 할 수 있는지조차 확실하지 않습니다 . su가 실행되면 현재 tty가 루트로 변경되어 작업자 스레드가 루트로 출력하는 것을 방지합니다.