-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Orphaned subprocesses may cause command substitution to hang. #134
Comments
The blocking only happens if the output of the function is captured with
However, I don't understand why the first example blocks. |
The following script works, see the discussion here for more detailed information: $ cat myclip.sh
#! /bin/bash
myclip()
{
printf '%s\n' 'hello world' |
xclip -selection clipboard -in > /dev/null
printf '%s\n' x
sleep 1
return
}
set -x
while true; do
y="$(myclip)"
done
$ bash myclip.sh
+ true
++ myclip
++ printf '%s\n' 'hello world'
++ xclip -selection clipboard -in
++ printf '%s\n' x
++ sleep 1
++ return
+ y=x
+ true
++ myclip
++ printf '%s\n' 'hello world'
++ xclip -selection clipboard -in
++ printf '%s\n' x
++ sleep 1
++ return
+ y=x
+ true
++ myclip
++ printf '%s\n' 'hello world'
++ xclip -selection clipboard -in
^C |
I have compared the code.
That is quite surprising. |
The following explanation comes from here given by
The following is the relevant discussion Helmut Waitzmann sent me via private email on this issue. Because it is related to this issue, I also forward it here for reference:
|
OP mis-understands how xclip works. When you run you immediately get your prompt back, but xclip remains running in the background (it forked itself) and will keep running so long as it owns the selection. When some other X11 application places data in the clipboard, only then it exits. And at that point, as described by Helmut in detail above, the writing end of the pipe will close, and your $(myclip) will return. Try this: run your script, and in another window: % xclip -o -selection clipboard you can read from the clipboard multiple times, and the original xclip from your script keeps serving that (has not exited the $(myclip) yet). but now do: % xclip -selection clipbord -in <<< "replace" and you'll see that the original xclip exits, myclip exits, and y is assigned. Without knowing exactly what you're trying to achieve, it is hard to advise you, but you may want to look into the '-quiet' and '-loops' options. '-quiet' will cause xclip not to fork (stays in foreground), and '-loops' will cause it to exit after a given number or readers have read the data it posted to the clipboard. |
This will put an additional $ man bash
** Here Strings
A variant of here documents, the format is:
[n]<<<word
The word undergoes tilde expansion, parameter and variable expansion,
command substitution, arithmetic expansion, and quote removal. Path‐
name expansion and word splitting are not performed. The result is
supplied as a single string, with a newline appended, to the command on
its standard input (or file descriptor n if n is specified).
** |
xclip
in a function, it cannot return to the main script.
FWIW I went thru the open bugs and pull requests yesterday, and saw several that were proposing to have xclip -i close stdout when forking into the background. So that would "fix" your example in the sense that myclip would no longer block, and instead return immediately, however, then you'll just be forking background xclip processes to replace themselves as fast as your shell can do so, which is almost certainly not what you want. What are you actually trying to accomplish? |
Originally the issue came up in my project x11docker. A few days ago I tried a solution using xclip in a function where it reads from both X servers, compares the clips, sends the latest clip to both, and returns the latest clip. This was the point where I was stuck because the function was blocked by stdout of xclip and I did not understand why. I don't think the behaviour of xclip should be changed as it is regular unix behaviour. Redirecting stdout already solves the issue as explained well above. Meanwhile I have a new implementation that does not use a function.
################ |
since xclip -i will not write to stdout, I think it actually does make sense to close stdout, and I think that was the conclusion drawn in several bugs, but I did not read them at all carefully.
I implemented something similar (locally) today, so that the -wait option works with -o, but not in exactly the way you want: what I implemented is that if no selection exists when you run xclip -o, it will wait up to the # of millisec specified by -wait, or indefinitely if -wait is negative. It should not be too hard to change that to do what you want (just bypass the "if no current selection" check).
I think I see what you're getting at, but I can't think of a solution. btw I just stumbled across this project the other day that sounds similar to what you're trying to do: https://www.chiark.greenend.org.uk/~sgtatham/utils/xclipglue.html have you seen it? |
At least with option
That sounds promising!
Thank you for the hint!
Basically I only need a waiting xclip other than with I've rewritten the code above a bit to split it into 4 loops.
|
sorry xclipglue didn't work, it really seems like it should do exactly what you want, and should ideally be more robust than a shell script. you might reach out to the author, he last made a change ~1.5 years ago, and his email is at the bottom of this page: https://www.chiark.greenend.org.uk/~sgtatham/utils/ re: your script, IIUC, you would be able to get rid of the sleep and the I have a couple hoops with my employer before I can submit a pull request for the wait feature I implemented. Once I submit that, the additional option you want should be pretty easy to add. |
Yes, exactly.
That sounds great! No need to hurry. |
Sounds good Martin, this week is busy and I'm on vacation next week, so while I might get to it this week, it could take a few weeks. |
@gklanderman Just want to kindly ask if you still have this project in mind? |
Hi @mviereck sorry I have had no time at all unfortunately.. I will try to make some progress in the next few weeks, ping me again if you don't hear anything.. |
Hi @mviereck sorry for the very long delay; not sure if you're still interested in this, but I no longer have employer hoops to jump through, and could probably make some time in the next month or so.. |
hi @gklanderman! I'm helping maintain xclip and all PRs are welcome anytime 👍 |
Jer @quartzjer great to hear.. I have some changes I am using locally which I will try to clean up and send PRs for as a first step.. Then I can look at this issue and the related ones I mentioned above. I see you're committing some changes lately.. do you have any plan for a release, and if so what's the timeline? Looks like the last release was 8 or so years ago.. |
On Ubuntu 20.04.3 LTS, I check the self-compiled git master version of xclip with the following bash script:
It will be blocked there forever, as shown below. In other words, when running
xclip
in a function, it cannot return to the main script.Please refer to the related discussions here and here.
Regards,
HZ
The text was updated successfully, but these errors were encountered: