Date: Thu, 13 Sep 2018 17:22:46 +0200 From: Edgar =?iso-8859-1?B?RnXf?= <e...@math.uni-bonn.de> Message-ID: <20180913152246.gm5...@trav.math.uni-bonn.de>
| > You're using an old version, not NetBSD current (or 8) right? | 6.1, mostly (for the ash part), yes. The jobs command implementation was just screwy back then. | Surely you've digested what SUS says about this. I didn't try too hard, | but I didn't grasp it. Could you explain what SUS allows? I use the current version of the POSIX standard, but yes... The standard says that when jobs is run (and "the termination status of a job is reported, so not "jobs -p") the job should be cleaned up. I believe that's just dump, "wait" is the way for scripts to clean up dead jobs. Part of the issue is that the POSIX wait command is primitive, and almost useless, so by having the jobs command act that way they provide a simple method to "make all the old stuff go away" easily. It's just the wrong solution. | > The dash behaviour (clearing the jobs table in a subshell) is technically | > correct (but as you say, makes life difficult) | I'm not sure whether we are talking about the same thing. We are. | What I mean is that if you have background jobs running, jobs -p will | surely list them. Yes. | However, if you want to use jobs -p output in a script, | the only way is to run it inside $(...). No, that's just the easy way. You can also do jobs -p >/tmp/whatever and then use the content of the file $(cat /tmp/whatever) if that is what you need. Then the jobs command is run in the correct environment. | That's a (potential) subshell environment, Well, technically, it is always that - it is just that when it can be determined no mods will be made, it can sometimes be avoided. POSIX goes to great lengths to explain how this is needed and how it might be done for "trap" but mostly just ignored it for "jobs" which has the same issue. | and in dash, the output of $(jobs -p) is always empty. It is in the -current (and I suspect 8.0) NetBSD sh too. But I will fix that soon. | While I suppose the words of SUS allow that, SUS also gives $(jobs -p) | as an example, which, in dash, could better be written "". This cannot | be intended. Not intended no, but it is technically correct - I suspect that the example needs extra explanation or special case handling, like is done with trap. I will file a bug report about it with the people who look after this stuff. | > the correct way to handle things like this is to not make a sub-shell | > to run "simple" command substitutions which do not affect the current | > shell environment. | I don't get that. Either we're talking past each other or I simply don't | understand what you mean. Here it could be either of those ... I was talking about how the shell could be implemented so that the behaviour that you want occurs. I suspect you're more concerned about what you can do with current shells. Those are indeed different things entirely. | Can you give a way where jobs -p and [insert your code here] echo "$j" | give the same output in dash? jobs -p >/tmp/mybobs j=$(cat /tmp/myjobs) rm /tmp/myjobs echo "$j" Of course, you'd normally use mktemp(1) rather than "/tmp/myjobs" | > jinx$ ./sh /tmp/parallel.jobs.sh 4 1 2 3 4 5 6 7 8 9 | Yes, that's the intended way (which I guess is obvious from the source). Not so obvious, but I got there eventually... | Would you say parallel.list.sh is portable? Yes, looks to be. Not that I have gone over every line of it with great care (and using echo rather than printf can sometimes be non-portable, you'd observe that if any of the args to jobs contained \ sequences, and you're using an echo that interprets those things.) I'd advise always using printf even if you do it something like echo() { NL='\n' case "$1" in -n) NL=; shift;; esac printf "%s${NL}" "$*" } and then just keep writing "echo" ... (nb: that \n is really the 2 chars \ and n, not a pseudonum for a literal newline char, though that would also work.) kre