while 루프는 변수 업데이트를 기억하지 못하는 것 같습니다. 관련 파이프가 없습니다.

while 루프는 변수 업데이트를 기억하지 못하는 것 같습니다. 관련 파이프가 없습니다.

표준 Mate 데스크탑을 사용하여 LMDE 2("Betsy")를 실행하고 있으며 다음 스크립트가 있습니다.

#!/bin/bash
# This script starts a specified terminal-binary in "Always on Top"-mode
# The assumption is, that 'wmctrl -l' sorts windows with the 
# in such a way, that the more recently a window has been created, 
# the lower it will be on the list ( compared to windows with the 
# same title).
#
# This is my assumption based on a short observation. The window 
# ids are probably given out in ascending hex numbers
# 
# Note: Using the pid will not help, since all terminals seem to
# be having the same pid
term_title_def='Terminal'
term_title='Terminal_top'
term_cmd="mate-terminal --title=$term_title"

# start terminal, wait for window  to appear and get id of most recently created window
# NOTE: a possible wrap-around of window ids has not been considered here!
eval $term_cmd
win_id=''
while [[ -z $win_id ]]; do
    win_id=$(wmctrl -l | grep "[[:blank:]]$term_title\$" | tail -n 1 | awk '{ print $1 }')
done

# DEBUG
touch /tmp/$win_id

# rename, set as "Always on top"
wmctrl -ir $win_id -T "$term_title_def"
wmctrl -ir $win_id -b add,above
wmctrl -ia $win_id

ps aufx재부팅 후 처음으로 MATE 패널 링크에서 스크립트를 실행할 때 스크립트는 while 루프를 종료하지 않습니다(검사 사용). 후속 호출은 예상대로 작동합니다. 즉, 링크가 내가 원하는 대로 작동합니다(위의 스크립트 주석 참조).

win_id그래서 왠지 MATE를 시작한 후 -test가 올바르게 확장되지 않은 것 같습니다(?) . while또는 그런 것.

왜 그런 겁니까?
지금 비슷한 것을 시도해 보겠습니다 while true; do stuff; break; done. 효과가 있기를 바랍니다.

업데이트:
위 루프를 다음으로 교체하세요 .while

while true; do
    win_id=$(wmctrl -l | grep "[[:blank:]]$term_title\$" | tail -n 1 | awk '{ print $1 }')
    [[ $win_id ]] && break
done

아무것도 바꾸지 않았습니다. 스크립트가 여전히 무한 루프에 갇히게 됩니다...

답변1

나는 이것이 어떻게 작동하는지 이해하지 못합니다. 당신이 달릴 때

eval $term_cmd 

터미널 창을 열면 이를 닫을 때까지 스크립트는 다른 작업을 수행하지 않습니다. 당신에게 필요한 것은:

$term_cmd &

백그라운드에서 실행하세요( eval필수는 아니므로 사용하지 마세요). 그러면 wmctrl출력의 마지막 줄도 선택할 필요가 없습니다 . 터미널 제목을 설정하고 있으므로 이를 유일한 것으로 만드십시오 grep.

#!/bin/bash
# This script starts a specified terminal-binary in "Always on Top"-mode
# The assumption is, that 'wmctrl -l' sorts windows with the 
# in such a way, that the more recently a window has been created, 
# the lower it will be on the list ( compared to windows with the 
# same title).
#
# This is my assumption based on a short observation. The window 
# ids are probably given out in ascending hex numbers
# 
# Note: Using the pid will not help, since all terminals seem to
# be having the same pid
term_title_def='Terminal'
term_title="Terminal_top_$$" ## Use the script's PID for a unique title
term_cmd="mate-terminal --title=$term_title"

## Start terminal. No need to wait, the loop will run until
## the terminal has been opened
$term_cmd &

win_id=''

while [[ -z "$win_id" ]]; do
    ## No need for '[[:blank:]]' and \$, you are using a unique title,
    ## keep the regex general. 
    win_id=$(wmctrl -l | grep "$term_title" | awk '{ print $1 }')
done
# DEBUG
touch /tmp/$win_id

# rename, set as "Always on top"
wmctrl -ir $win_id -T "$term_title_def"
wmctrl -ir $win_id -b add,above
wmctrl -ia $win_id

답변2

while 루프는 하위 셸에서 실행되므로 하위 셸의 변수에 대한 수정 사항은 상위 셸에 보고되지 않습니다.https://stackoverflow.com/questions/16854280/modifying-variable-inside-while-loop-is-not-remembered

내 측의 두 번째 질문에 대해서는 다음과 같습니다.

$ while true; do toto=plop; echo $toto; [[ $toto ]] && break ; done 
plop

$win_id따라서 루프 내부의 정의에 실제 문제가 있다고 생각합니다.

관련 정보