2

I am running LMDE 2 ( 'Betsy') with the standard Mate desktop and I have the following script:

#!/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

Somehow, the script never exits the while loop ( checked that with ps aufx) on first running it from a MATE-panel link after reboot. The subsequent calls work as expected, that is the link does what I want it to ( see script comments above).

So, somehow, right after starting up MATE, win_id isn't expanded correctly in while-test, I suppose (?). Or something like that.

Why is that?
I will now try something like while true; do stuff; break; done instead and hope it'll work...

UPDATE:
Substituting the while-loop above with the following

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

didn't change anything. The script is still stuck in an infinite loop...

  • Maybe the assignment in while loop is culprit, win_id wasn't updated. – cuonglm Sep 8 '15 at 6:38
  • What exactly do you mean? What could be wrong with the assignment? Also, then why does the script work on subsequent calls? – polynomial_donut Sep 8 '15 at 6:39
  • 1
    Maybe wmctrl -l | grep "[[:blank:]]$term_title\$" | tail -n 1 | awk '{ print $1 }' won't return anything at the first time, try running it before assignment. – cuonglm Sep 8 '15 at 6:40
  • But then, don't you think that the script should never work - I have a hard time imagining that only on the first call of the script, the first call of that command never returns anything ( I might still try what you've suggested later on, however I'd still like to know the reason for that weird behavior then)? But it does on the second call, for example... – polynomial_donut Sep 8 '15 at 6:41
  • 3
    Try running the script with set -x before while loop. If possible, post the output here – SHW Sep 8 '15 at 6:43
0

I don't see how this could work. When you run

eval $term_cmd 

you will open a terminal window and the script won't do anything else until you close it. What you need is:

$term_cmd &

Run it in the background (and don't use eval, it's not needed). Then, you also don't need to select the last line of wmctrl's output., You are setting the terminal title, so set it to something unique and grep that:

#!/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
  • "$term_cmd" & does not work. I've tried that before. The bash will try to interpret the whole string as a single command and fail. Even omitting the double quotes did not yield anything better than what I've had so far... and are you sure about the $$-part? I guess you forgot there were single quotes around the assignment string – polynomial_donut Sep 8 '15 at 21:33
  • oh I oversaw you changed it to double quotes, never mind :) I think this answer is ready to be approved once my edits are accepted – polynomial_donut Sep 8 '15 at 21:39
  • @polynomial_donut what edits? I haven't seen any suggested edits on this answer. What do you need? – terdon Sep 8 '15 at 23:10
  • Quoting my own former comment: "$term_cmd" & does not work. The edit has been approved of already. – polynomial_donut Sep 8 '15 at 23:38
  • @polynomial_donut it does here. The quotes might make a difference (not at my pc now, so I can't check, I didn't quote it in my test) but eval is not needed. In any case, the main point is that you need to run the terminal in the background. – terdon Sep 8 '15 at 23:40
-2

The while loop is executed in a subshell, so any modification made to the variable in the subshell is not reported into the father shell : https://stackoverflow.com/questions/16854280/modifying-variable-inside-while-loop-is-not-remembered

For the second issue on my side i have :

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

So i do think you have a real problem with the definition of $win_id inside the loop.

  • 1
    That's the pipe cause the subshell, not while loop. It's not the same in this question. – cuonglm Sep 8 '15 at 9:43
  • @cuonglm is right, you should also read my question completely. If the problem was a subshell, then with the loop-variant I have posted, the script should work, shouldn't it...? – polynomial_donut Sep 8 '15 at 9:46
  • Yeah sorry for the first explanation, the pipe creates the subshell not the while loop. I see an echo $win_id, what does it display inside the infinite loop ? – netmonk Sep 8 '15 at 9:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.