xdg-open block until spawned process is killed

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
1
down vote

favorite
1












I have a lot of documents to view, and I'd like to view them one by one, so the next opens when I close the previous.



I've done this with evince before, with



for i in `ls | grep .pdf`; do evince $i; done


However doing the same with xdg-open fails because xdg-open does not block like evince does.



Is there a way to run the same for loop, but with xdg-open, so that when I close the application that was opened, the next iteration of the for loop runs?







share|improve this question






















  • short answer: no. long answer: modify the source
    – Ipor Sircer
    Mar 5 at 16:32














up vote
1
down vote

favorite
1












I have a lot of documents to view, and I'd like to view them one by one, so the next opens when I close the previous.



I've done this with evince before, with



for i in `ls | grep .pdf`; do evince $i; done


However doing the same with xdg-open fails because xdg-open does not block like evince does.



Is there a way to run the same for loop, but with xdg-open, so that when I close the application that was opened, the next iteration of the for loop runs?







share|improve this question






















  • short answer: no. long answer: modify the source
    – Ipor Sircer
    Mar 5 at 16:32












up vote
1
down vote

favorite
1









up vote
1
down vote

favorite
1






1





I have a lot of documents to view, and I'd like to view them one by one, so the next opens when I close the previous.



I've done this with evince before, with



for i in `ls | grep .pdf`; do evince $i; done


However doing the same with xdg-open fails because xdg-open does not block like evince does.



Is there a way to run the same for loop, but with xdg-open, so that when I close the application that was opened, the next iteration of the for loop runs?







share|improve this question














I have a lot of documents to view, and I'd like to view them one by one, so the next opens when I close the previous.



I've done this with evince before, with



for i in `ls | grep .pdf`; do evince $i; done


However doing the same with xdg-open fails because xdg-open does not block like evince does.



Is there a way to run the same for loop, but with xdg-open, so that when I close the application that was opened, the next iteration of the for loop runs?









share|improve this question













share|improve this question




share|improve this question








edited Mar 5 at 15:17









Jeff Schaller

31.2k846105




31.2k846105










asked Mar 5 at 15:15









Brydon Gibson

13215




13215











  • short answer: no. long answer: modify the source
    – Ipor Sircer
    Mar 5 at 16:32
















  • short answer: no. long answer: modify the source
    – Ipor Sircer
    Mar 5 at 16:32















short answer: no. long answer: modify the source
– Ipor Sircer
Mar 5 at 16:32




short answer: no. long answer: modify the source
– Ipor Sircer
Mar 5 at 16:32










1 Answer
1






active

oldest

votes

















up vote
2
down vote



accepted










I couldn't find a clean way, so this is a work-around; open each file then run a busy-loop waiting for "the" matching process to exit. I've also updated your for loop so that you're not parsing ls and are quoting the filename parameter:



#!/bin/bash

for i in *.pdf
do
xdg-open "$i"
t=$(tty)
t=$t##/dev/
s=$(ps -o session= -p $$)
while pgrep -f "$i" --terminal "$t" --uid "$(id -u)" --session "$s" >/dev/null 2>&1
do
sleep 1
done
done


The assumption here is that xdg-open will open the file; that process gets forked off by the desktop environment and control returns to the script. The script then gathers the tty, session, and current user ID and asks pgrep to look for (the) process matching all of these criteria:



  • full process name includes the filename from the loop

  • the associated terminal is the one we're running from

  • the UID of the process matches ours

  • the process session matches ours

... all in an attempt to catch only the corresponding process that xdg-open launched.



When that process no longer exists, we continue with the for loop on to the next file.



If the one-second delay is too long, you could replace that (on Linux) with a sub-second sleep, or a simple : for no waiting at all.






share|improve this answer




















  • This is an awesome solution! A little hacky but it gets the job done. Very smart.
    – Brydon Gibson
    Mar 5 at 16:40










  • Thank you! Don't feel rushed to accept my (or any first) answer; I'm not an expert at desktop environments, so there may be a better way.
    – Jeff Schaller
    Mar 5 at 16:42











  • Unfortunately this will fail if the file is opened by an existing process. You can see this happen e.g. with gedit, if that’s the default editor for text files: start gedit, then xdg-open a text file; the file will open in gedit, and the above script won’t match anything.
    – Stephen Kitt
    Mar 6 at 12:21










  • @StephenKitt would the gedit process have to have started from the same tty/session, too?
    – Jeff Schaller
    Mar 6 at 12:32










  • That’s not sufficient, because the file name doesn’t show up on the command line of the running process.
    – Stephen Kitt
    Mar 6 at 12:44










Your Answer







StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f428296%2fxdg-open-block-until-spawned-process-is-killed%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote



accepted










I couldn't find a clean way, so this is a work-around; open each file then run a busy-loop waiting for "the" matching process to exit. I've also updated your for loop so that you're not parsing ls and are quoting the filename parameter:



#!/bin/bash

for i in *.pdf
do
xdg-open "$i"
t=$(tty)
t=$t##/dev/
s=$(ps -o session= -p $$)
while pgrep -f "$i" --terminal "$t" --uid "$(id -u)" --session "$s" >/dev/null 2>&1
do
sleep 1
done
done


The assumption here is that xdg-open will open the file; that process gets forked off by the desktop environment and control returns to the script. The script then gathers the tty, session, and current user ID and asks pgrep to look for (the) process matching all of these criteria:



  • full process name includes the filename from the loop

  • the associated terminal is the one we're running from

  • the UID of the process matches ours

  • the process session matches ours

... all in an attempt to catch only the corresponding process that xdg-open launched.



When that process no longer exists, we continue with the for loop on to the next file.



If the one-second delay is too long, you could replace that (on Linux) with a sub-second sleep, or a simple : for no waiting at all.






share|improve this answer




















  • This is an awesome solution! A little hacky but it gets the job done. Very smart.
    – Brydon Gibson
    Mar 5 at 16:40










  • Thank you! Don't feel rushed to accept my (or any first) answer; I'm not an expert at desktop environments, so there may be a better way.
    – Jeff Schaller
    Mar 5 at 16:42











  • Unfortunately this will fail if the file is opened by an existing process. You can see this happen e.g. with gedit, if that’s the default editor for text files: start gedit, then xdg-open a text file; the file will open in gedit, and the above script won’t match anything.
    – Stephen Kitt
    Mar 6 at 12:21










  • @StephenKitt would the gedit process have to have started from the same tty/session, too?
    – Jeff Schaller
    Mar 6 at 12:32










  • That’s not sufficient, because the file name doesn’t show up on the command line of the running process.
    – Stephen Kitt
    Mar 6 at 12:44














up vote
2
down vote



accepted










I couldn't find a clean way, so this is a work-around; open each file then run a busy-loop waiting for "the" matching process to exit. I've also updated your for loop so that you're not parsing ls and are quoting the filename parameter:



#!/bin/bash

for i in *.pdf
do
xdg-open "$i"
t=$(tty)
t=$t##/dev/
s=$(ps -o session= -p $$)
while pgrep -f "$i" --terminal "$t" --uid "$(id -u)" --session "$s" >/dev/null 2>&1
do
sleep 1
done
done


The assumption here is that xdg-open will open the file; that process gets forked off by the desktop environment and control returns to the script. The script then gathers the tty, session, and current user ID and asks pgrep to look for (the) process matching all of these criteria:



  • full process name includes the filename from the loop

  • the associated terminal is the one we're running from

  • the UID of the process matches ours

  • the process session matches ours

... all in an attempt to catch only the corresponding process that xdg-open launched.



When that process no longer exists, we continue with the for loop on to the next file.



If the one-second delay is too long, you could replace that (on Linux) with a sub-second sleep, or a simple : for no waiting at all.






share|improve this answer




















  • This is an awesome solution! A little hacky but it gets the job done. Very smart.
    – Brydon Gibson
    Mar 5 at 16:40










  • Thank you! Don't feel rushed to accept my (or any first) answer; I'm not an expert at desktop environments, so there may be a better way.
    – Jeff Schaller
    Mar 5 at 16:42











  • Unfortunately this will fail if the file is opened by an existing process. You can see this happen e.g. with gedit, if that’s the default editor for text files: start gedit, then xdg-open a text file; the file will open in gedit, and the above script won’t match anything.
    – Stephen Kitt
    Mar 6 at 12:21










  • @StephenKitt would the gedit process have to have started from the same tty/session, too?
    – Jeff Schaller
    Mar 6 at 12:32










  • That’s not sufficient, because the file name doesn’t show up on the command line of the running process.
    – Stephen Kitt
    Mar 6 at 12:44












up vote
2
down vote



accepted







up vote
2
down vote



accepted






I couldn't find a clean way, so this is a work-around; open each file then run a busy-loop waiting for "the" matching process to exit. I've also updated your for loop so that you're not parsing ls and are quoting the filename parameter:



#!/bin/bash

for i in *.pdf
do
xdg-open "$i"
t=$(tty)
t=$t##/dev/
s=$(ps -o session= -p $$)
while pgrep -f "$i" --terminal "$t" --uid "$(id -u)" --session "$s" >/dev/null 2>&1
do
sleep 1
done
done


The assumption here is that xdg-open will open the file; that process gets forked off by the desktop environment and control returns to the script. The script then gathers the tty, session, and current user ID and asks pgrep to look for (the) process matching all of these criteria:



  • full process name includes the filename from the loop

  • the associated terminal is the one we're running from

  • the UID of the process matches ours

  • the process session matches ours

... all in an attempt to catch only the corresponding process that xdg-open launched.



When that process no longer exists, we continue with the for loop on to the next file.



If the one-second delay is too long, you could replace that (on Linux) with a sub-second sleep, or a simple : for no waiting at all.






share|improve this answer












I couldn't find a clean way, so this is a work-around; open each file then run a busy-loop waiting for "the" matching process to exit. I've also updated your for loop so that you're not parsing ls and are quoting the filename parameter:



#!/bin/bash

for i in *.pdf
do
xdg-open "$i"
t=$(tty)
t=$t##/dev/
s=$(ps -o session= -p $$)
while pgrep -f "$i" --terminal "$t" --uid "$(id -u)" --session "$s" >/dev/null 2>&1
do
sleep 1
done
done


The assumption here is that xdg-open will open the file; that process gets forked off by the desktop environment and control returns to the script. The script then gathers the tty, session, and current user ID and asks pgrep to look for (the) process matching all of these criteria:



  • full process name includes the filename from the loop

  • the associated terminal is the one we're running from

  • the UID of the process matches ours

  • the process session matches ours

... all in an attempt to catch only the corresponding process that xdg-open launched.



When that process no longer exists, we continue with the for loop on to the next file.



If the one-second delay is too long, you could replace that (on Linux) with a sub-second sleep, or a simple : for no waiting at all.







share|improve this answer












share|improve this answer



share|improve this answer










answered Mar 5 at 16:36









Jeff Schaller

31.2k846105




31.2k846105











  • This is an awesome solution! A little hacky but it gets the job done. Very smart.
    – Brydon Gibson
    Mar 5 at 16:40










  • Thank you! Don't feel rushed to accept my (or any first) answer; I'm not an expert at desktop environments, so there may be a better way.
    – Jeff Schaller
    Mar 5 at 16:42











  • Unfortunately this will fail if the file is opened by an existing process. You can see this happen e.g. with gedit, if that’s the default editor for text files: start gedit, then xdg-open a text file; the file will open in gedit, and the above script won’t match anything.
    – Stephen Kitt
    Mar 6 at 12:21










  • @StephenKitt would the gedit process have to have started from the same tty/session, too?
    – Jeff Schaller
    Mar 6 at 12:32










  • That’s not sufficient, because the file name doesn’t show up on the command line of the running process.
    – Stephen Kitt
    Mar 6 at 12:44
















  • This is an awesome solution! A little hacky but it gets the job done. Very smart.
    – Brydon Gibson
    Mar 5 at 16:40










  • Thank you! Don't feel rushed to accept my (or any first) answer; I'm not an expert at desktop environments, so there may be a better way.
    – Jeff Schaller
    Mar 5 at 16:42











  • Unfortunately this will fail if the file is opened by an existing process. You can see this happen e.g. with gedit, if that’s the default editor for text files: start gedit, then xdg-open a text file; the file will open in gedit, and the above script won’t match anything.
    – Stephen Kitt
    Mar 6 at 12:21










  • @StephenKitt would the gedit process have to have started from the same tty/session, too?
    – Jeff Schaller
    Mar 6 at 12:32










  • That’s not sufficient, because the file name doesn’t show up on the command line of the running process.
    – Stephen Kitt
    Mar 6 at 12:44















This is an awesome solution! A little hacky but it gets the job done. Very smart.
– Brydon Gibson
Mar 5 at 16:40




This is an awesome solution! A little hacky but it gets the job done. Very smart.
– Brydon Gibson
Mar 5 at 16:40












Thank you! Don't feel rushed to accept my (or any first) answer; I'm not an expert at desktop environments, so there may be a better way.
– Jeff Schaller
Mar 5 at 16:42





Thank you! Don't feel rushed to accept my (or any first) answer; I'm not an expert at desktop environments, so there may be a better way.
– Jeff Schaller
Mar 5 at 16:42













Unfortunately this will fail if the file is opened by an existing process. You can see this happen e.g. with gedit, if that’s the default editor for text files: start gedit, then xdg-open a text file; the file will open in gedit, and the above script won’t match anything.
– Stephen Kitt
Mar 6 at 12:21




Unfortunately this will fail if the file is opened by an existing process. You can see this happen e.g. with gedit, if that’s the default editor for text files: start gedit, then xdg-open a text file; the file will open in gedit, and the above script won’t match anything.
– Stephen Kitt
Mar 6 at 12:21












@StephenKitt would the gedit process have to have started from the same tty/session, too?
– Jeff Schaller
Mar 6 at 12:32




@StephenKitt would the gedit process have to have started from the same tty/session, too?
– Jeff Schaller
Mar 6 at 12:32












That’s not sufficient, because the file name doesn’t show up on the command line of the running process.
– Stephen Kitt
Mar 6 at 12:44




That’s not sufficient, because the file name doesn’t show up on the command line of the running process.
– Stephen Kitt
Mar 6 at 12:44












 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f428296%2fxdg-open-block-until-spawned-process-is-killed%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

How to check contact read email or not when send email to Individual?

Bahrain

Postfix configuration issue with fips on centos 7; mailgun relay