Commands in a function not executed in sequence?

Hello! I’m using fvwm 2.6.5 on Debian sid.

I have this function in my fvwm2rc:

Key z   A  4 MyTest

DestroyFunc MyTest
AddToFunc MyTest
+ I    Exec echo 'Test1' | tee -a /home/alex/fvwmtest
+ I    Exec echo 'Test2' | tee -a /home/alex/fvwmtest
+ I    Exec echo 'Test3' | tee -a /home/alex/fvwmtest
+ I    Exec echo 'Test4' | tee -a /home/alex/fvwmtest
+ I    Exec echo 'Test5' | tee -a /home/alex/fvwmtest
+ I    Exec echo 'Test6' | tee -a /home/alex/fvwmtest
+ I    Exec echo '=======' | tee -a /home/alex/fvwmtest

And then I examine the content of /home/alex/fvwmtest after pressing Mod4+z twice:

[code]$ cat fvwmtest



It seems that they are not in the correct order? I’m confused… :frowning:

Any help greatly appreciated! Thanks in advance!

I to get the same behavior in 2.6.6. My observations are the following. First what the manpage says about + I:

What I think is happening is they are being executed in order, but ‘Exec’ doesn’t wait for the execution to complete, so it starts the next one in the list before the first one is done. The commands don’t all take the same speed to complete so it just happens that some complete faster than others so the appearance is not in order.

If you read the manpage under the description for ‘Exec’ you will see this mentioned:

The manpage has a small section on complex function scripting:

In order to get what you have done to appear in order you need fvwm to wait until one command is completed to do the other. One method to do that is PipeRead.

[code]DestroyFunc TestFunc
AddToFunc TestFunc

  • I PipeRead echo "Test1" > $HOME/tmp/testfunc.txt
  • I PipeRead echo "Test2" >> $HOME/tmp/testfunc.txt
  • I PipeRead echo "Test3" >> $HOME/tmp/testfunc.txt
  • I PipeRead echo "Test4" >> $HOME/tmp/testfunc.txt
  • I PipeRead echo "Test5" >> $HOME/tmp/testfunc.txt
  • I PipeRead echo "Test6" >> $HOME/tmp/testfunc.txt

So using PipeRead, the function will wait for the completion of the command in PipeRead before moving on to the next line. So the above will print in order.

Note, be careful with PipeRead, as it will try to execute any of the stdout that is produced by the command (hence why I used >> vs tee, otherwise it will have trouble with the undefined functions Test?). Also the PipeRead will wait for the command to complete, so on complex scripts this could cause fvwm to wait as well.

If you explain what it is you are trying to achieve, you may get some better tips.

Thank you very much for the detailed explanation! :smiley: It is definitely my fault for missing that part in the man page.
To verify I’ve conducted a new test. Instead of echoing to a file, I use the ‘Echo’ command to print the text to stdout:

[code]DestroyFunc MyTest
AddToFunc MyTest

  • I Echo test1
  • I Echo test2
  • I Echo test3
  • I Echo test4
  • I Echo test5

I assume the internal ‘Echo’ is fast enough to prevent the aforementioned issue? And indeed, they appear in the exact order every time I try.

BTW, do I have to take extra precautions to ensure the commands execute one after another? For example in some custom functions tweaking the focus policy, where the command execution order really matters.

Thank you again for pointing me the right direction! I’ll research more before posting further questions. :smiley:

"Fast enough is not the point here. Usually FVWM executes its commands one after the other, except special things like shells started by “Exec” or appearance commands that are listed in the manpage under “Delayed Execution of Commands”. “Exec” starts a shell, passes the given commands to it and forgets it. The shell then processes the commands before it exits itself. You can provide the shell command “exec” following the FVWM command “Exec”: Exec exec echo Test1 This will not make the shell call the “echo” command but replace itself by the “echo” program, i.e. the shell will immediately cease to exist and hence execute a bit faster, but there’s still no guarantee concerning synchroization. In fact, doing so is always recommended to prevent useless shells hanging around. You only need such a shell for non-trivial control structures like Exec test $a -ne 0 || echo a is zero.


Thank you! I got a better understanding now.

I wrote the reasoning for this years ago: … onisation/

– Thomas Adam