Re: Idea: jobs(1) -i to print only :%ID:s
Chet Ramey wrote in <7402031f-424c-4766-ba70-71771c9dc...@case.edu>: |On 11/8/23 8:12 PM, Steffen Nurpmeso wrote: |> The "problem" with the current way bash is doing it is that bash's |> job handling does not recognize jobs die under the hood: |> |>$ jobs |>[1]- Stopped LESS= less -RIFe README |>[2]+ Stopped LESS= less -RIFe TODO |>$ kill $(jobs -p) |>$ |> |> ^ nothing |> |>$ jobs |>[1]- Stopped LESS= less -RIFe README |>[2]+ Stopped LESS= less -RIFe TODO | |Yes, the jobs are still stopped, and will remain stopped until they get |a SIGCONT. Do you think that kill, when given a pid argument, should look |up any job associated with that pid and send it a SIGCONT? Or should it |send a SIGCONT to the pid unconditionally? If so, what about other |processes in that job? Today GMANE (through which i read bug-bash@) posted this entire thread again! And because i am a bit afraid of Danish dynamite (especially relaxed, or on-holiday such sort), i thought i better do something. So what i did was as below (any usage of job_by_pid without args 2+3==0?), and i even compiled and tested it (a bit). Maybe you like it! Ciao already here! diff --git a/builtins/kill.def b/builtins/kill.def index c655092e7b..e3caabbf73 100644 --- a/builtins/kill.def +++ b/builtins/kill.def @@ -85,6 +85,11 @@ int kill_builtin (list) WORD_LIST *list; { +#if defined (JOB_CONTROL) + sigset_t set, oset; + JOB *j; + int job; +#endif int sig, any_succeeded, listing, saw_signal, dflags; char *sigspec, *word; pid_t pid; @@ -194,6 +199,14 @@ use_sigspec: { pid = (pid_t) pid_value; +#if defined (JOB_CONTROL) + BLOCK_CHILD (set, oset); + job = get_job_by_pid ((pid_t) pid_value, 0, 0); + if (job != NO_JOB) + goto jisjob; + UNBLOCK_CHILD (oset); +#endif + if (kill_pid (pid, sig, pid < -1) < 0) { if (errno == EINVAL) @@ -214,10 +227,6 @@ use_sigspec: else if (*word) /* Posix.2 says you can kill without job control active (4.32.4) */ { /* Must be a job spec. Check it out. */ - int job; - sigset_t set, oset; - JOB *j; - BLOCK_CHILD (set, oset); job = get_job_spec (list); @@ -229,6 +238,7 @@ use_sigspec: CONTINUE_OR_FAIL; } +jisjob: j = get_job_by_jid (job); /* Job spec used. Kill the process group. If the job was started without job control, then its pgrp == shell_pgrp, so we have --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt) | | Only in December: lightful Dubai COP28 Narendra Modi quote: | A small part of humanity has ruthlessly exploited nature. | But the entire humanity is bearing the cost of it, | especially the inhabitants of the Global South. | The selfishness of a few will lead the world into darkness, | not just for themselves but for the entire world.
Re: Idea: jobs(1) -i to print only :%ID:s
On Fri, Nov 10, 2023 at 10:54:52AM -0800, Eric Pruitt wrote: > > A seq command appeared in Version 8 AT UNIX. This version of seq > > appeared in NetBSD 3.0 and was ported to OpenBSD 7.1. Ah, I'm a year and a half behind. OpenBSD 7.1 was released April 2022.
Re: Idea: jobs(1) -i to print only :%ID:s
On Fri, Nov 10, 2023 at 01:22:54PM -0500, Greg Wooledge wrote: > It most definitely is *not* everywhere. It's part of GNU coreutils, > and is generally not present on any system that does't use those (BSDs > and commercial Unixes for example). >From _seq(1)_ on FreeBSD: > The seq command first appeared in Version 8 AT UNIX. A seq command > appeared in NetBSD 3.0, and was ported to FreeBSD 9.0. This command > was based on the command of the same name in Plan 9 from Bell Labs and > the GNU core utilities. The GNU seq command first appeared in the 1.13 > shell utilities release. >From _seq(1)_ on OpenBsd: > A seq command appeared in Version 8 AT UNIX. This version of seq > appeared in NetBSD 3.0 and was ported to OpenBSD 7.1.
Re: Idea: jobs(1) -i to print only :%ID:s
Greg Wooledge wrote in : |On Fri, Nov 10, 2023 at 06:59:10PM +0100, Steffen Nurpmeso wrote: |> Sequences are also bash-only (though seq(1) is |> everywhere). | |It most definitely is *not* everywhere. It's part of GNU coreutils, |and is generally not present on any system that does't use those (BSDs |and commercial Unixes for example). It is everywhere. Including my static busybox. Which BSD do you use? --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
Re: Idea: jobs(1) -i to print only :%ID:s
On Fri, Nov 10, 2023 at 06:59:10PM +0100, Steffen Nurpmeso wrote: > Sequences are also bash-only (though seq(1) is > everywhere). It most definitely is *not* everywhere. It's part of GNU coreutils, and is generally not present on any system that does't use those (BSDs and commercial Unixes for example).
Re: Idea: jobs(1) -i to print only :%ID:s
Chet Ramey wrote in <7402031f-424c-4766-ba70-71771c9dc...@case.edu>: |On 11/8/23 8:12 PM, Steffen Nurpmeso wrote: |> The "problem" with the current way bash is doing it is that bash's |> job handling does not recognize jobs die under the hood: |> |>$ jobs |>[1]- Stopped LESS= less -RIFe README |>[2]+ Stopped LESS= less -RIFe TODO |>$ kill $(jobs -p) |>$ |> |> ^ nothing |> |>$ jobs |>[1]- Stopped LESS= less -RIFe README |>[2]+ Stopped LESS= less -RIFe TODO | |Yes, the jobs are still stopped, and will remain stopped until they get |a SIGCONT. Do you think that kill, when given a pid argument, should look |up any job associated with that pid and send it a SIGCONT? Or should it |send a SIGCONT to the pid unconditionally? If so, what about other |processes in that job? Hm coming from this other side is also an interesting thing, but which i did not think about. I mean .. "if the lookup is fast" kill(1) could of course throw all of its arguments against the list of tracked processes, not only %job specifications. (Having said that i am personally still hoping for a shell syntax extension that closes the race condition of PID reuse against kill(1), in that if i "kill -TERM ID" where ID is known to be a monitored process, but which has terminated, the shell will reject doing the kill as such. Also the "kill -0 && kill -X" gap is a race in itself. But that is of course a different topic.) --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
Re: Idea: jobs(1) -i to print only :%ID:s
Hello. Oğuz wrote in : |On Thursday, November 9, 2023, Steffen Nurpmeso wrote: |> I mean some scripting on "jobs | wc -l" would do that, though. :( |> Maybe i should just write a function that builds the string |> necessary to do what i wanted with %* or "%1-2 %4" etc. |> Eh. Forget about it. | |Can't you abuse jobs -x somehow? Like this perhaps | |jobs -x printf '%s\n' %{1..100} | awk '!/%/{print "%"NR}' Well i first thought "this is darn smart", but then realized this is at the level of that wc -l thing which is definetely the wrong thing to do. Sequences are also bash-only (though seq(1) is everywhere). But thanks. --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
Re: Idea: jobs(1) -i to print only :%ID:s
On 11/8/23 8:12 PM, Steffen Nurpmeso wrote: The "problem" with the current way bash is doing it is that bash's job handling does not recognize jobs die under the hood: $ jobs [1]- Stopped LESS= less -RIFe README [2]+ Stopped LESS= less -RIFe TODO $ kill $(jobs -p) $ ^ nothing $ jobs [1]- Stopped LESS= less -RIFe README [2]+ Stopped LESS= less -RIFe TODO Yes, the jobs are still stopped, and will remain stopped until they get a SIGCONT. Do you think that kill, when given a pid argument, should look up any job associated with that pid and send it a SIGCONT? Or should it send a SIGCONT to the pid unconditionally? If so, what about other processes in that job? -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/
Re: Idea: jobs(1) -i to print only :%ID:s
On Thursday, November 9, 2023, Steffen Nurpmeso wrote: > > I mean some scripting on "jobs | wc -l" would do that, though. :( > Maybe i should just write a function that builds the string > necessary to do what i wanted with %* or "%1-2 %4" etc. > Eh. Forget about it. > Can't you abuse jobs -x somehow? Like this perhaps jobs -x printf '%s\n' %{1..100} | awk '!/%/{print "%"NR}' -- Oğuz
Re: Idea: jobs(1) -i to print only :%ID:s
Greg Wooledge wrote in : |On Thu, Nov 09, 2023 at 10:17:35PM +0100, Andreas Schwab wrote: |> On Nov 09 2023, Greg Wooledge wrote: |>> re='^\[([0-9]+)\]' .. |>> while IFS= read -r line; do |>> if [[ $line =~ $re ]]; then ... |> That fails for multi-line commands that happen to contain matches for |> re. |> |> $ (sleep 100; printf $'\n[100]\n') & | |Fair enough. I believe *nothing* would work in that case; the output of |"jobs -l" cannot be safely parsed in its current form. | |Adding a NUL-delimited output option might work around that, but if we're |modifying the jobs builtin, we might as well just add the -i or -j option |instead. As i started this: it should simply quote it so that "i=$(eval $x)" brings back the real value. I use that excessively for the mutilated shell capabilities of the MUA i maintain (am at to at least improve that a bit for ie "eval set \$(($1+1))".). --End of --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
Re: Idea: jobs(1) -i to print only :%ID:s
Robert Elz wrote in <15529.1699569...@jacaranda.noi.kre.to>: |Date:Thu, 9 Nov 2023 16:55:50 -0500 |From:Greg Wooledge |Message-ID: | || I believe *nothing* would work in that case; | |There's no requirement (in fact, it is probably not a good idea) for |newlines in the output to be printed literally - whether entered literally |or using $'\n'. Bash could always just output $'\n' for a newline. I'd only wish tools would start to create quoted ranges of maximum length, instead of these atomar quote orgies. No normal human being can grasp that. (In my opinion. I mean my bank account has a four digit number, and that is tough stuff to change. :)) ... --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
Re: Idea: jobs(1) -i to print only :%ID:s
Robert Elz wrote in <7989.1699564...@jacaranda.noi.kre.to>: |Date:Thu, 09 Nov 2023 21:04:28 +0100 |From:Steffen Nurpmeso |Message-ID: <20231109200428.8g9lz%stef...@sdaoden.eu> | || ash(1) and busybox ash(1) do not even support jobs -l in a function \ || (yet). | |That seems unlikely, ash based shells mostly don't care whether the \ |commands |they're running are in a function or not, except for those few commands for |which that is important (like return, local, etc). | |Are you sure that you're not seeing the effects of running jobs in a |subshell environment (in a command substitution) - where no jobs have |yet been created in that environment. Modern shells allow jobs (like |trap) there, as a way to get the parent shell's jobs (or traps), but |even now (in the latest drafts) POSIX does not require that jobs works |that way (it does for trap, in very limited cases). That was taking me too literally. It seems monitor mode and all its tracked jobs are not available in a subshell, not even within { ; }. ... Hmm. Well have i done this afternoon: #?0|kent:tmp$ dash #?0|kent:tmp$ LESS= less t.rc & #?0|kent:tmp$ LESS= less t.sh & #?0|kent:tmp$ jobs -l [2] + 18950 Stopped (tty output) less t.sh [1] - 18948 Stopped less t.rc #?0|kent:tmp$ { jobs -l; } [2] + 18950 Stopped (tty output) less t.sh [1] - 18948 Stopped less t.rc #?0|kent:tmp$ ( jobs -l; ) #?0|kent:tmp$ listem() { > jobs -l > } #?0|kent:tmp$ listem [2] + 18950 Stopped (tty output) less t.sh [1] - 18948 Stopped less t.rc #?0|kent:tmp$ $( listem ) #?0|kent:tmp$ So i would have to use output redirection in order to avoid calling listem() in a $() construct. It seems the simple issue is about to become a monster. --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
Re: Idea: jobs(1) -i to print only :%ID:s
Andreas Schwab wrote in <87h6lueids@igel.home>: |On Nov 09 2023, Greg Wooledge wrote: | |> re='^\[([0-9]+)\]' |> jobspecs=() |> while IFS= read -r line; do |> if [[ $line =~ $re ]]; then |> jobspecs+=( "%${BASH_REMATCH[1]}" ) |> fi |> done < <(jobs -l) | |That fails for multi-line commands that happen to contain matches for |re. | |$ (sleep 100; printf $'\n[100]\n') & Bummer. Same is true for my thing. Seems to me bash(1) should quote the output of jobs -l. --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
Re: Idea: jobs(1) -i to print only :%ID:s
Date:Thu, 9 Nov 2023 16:55:50 -0500 From:Greg Wooledge Message-ID: | I believe *nothing* would work in that case; There's no requirement (in fact, it is probably not a good idea) for newlines in the output to be printed literally - whether entered literally or using $'\n'. Bash could always just output $'\n' for a newline. It could use $' instead of ' for everything intended to be quoted (and then escape other non-printing characters as well, so output which might lock the terminal wouldn't appear literally, etc). | the output of "jobs -l" cannot be safely parsed in its current form. It probably isn't a good idea, regardless of processing the output, as jobs -l (when it reports process termination, which it can) is supposed to remove the job from the jobs table, and forget it - which generally isn't what is wanted when the output is being parsed. How that operates when the jobs -l is being executed in a subshell but reporting the status of its parent is less clear (and it most probably simply doesn't happen - but there are no guarantees). That is if the jobs command works that way at all in a particular shell. | but if we're modifying the jobs builtin, we might as well just add | the -i or -j option instead. ash based shells have a jobid builtin, which takes anything which identifies a job, and prints a list of its process ids. The NetBSD variant of that has been extended to be able to instead print job identifiers (%1 etc) the process group id, or the lead process id (what $! would have been). I have just added (not yet committed) the ability to do that for all jobs (or any of a listed set) rather than just for one which used to be the case. This command never alters the jobs table, so is safer to use, and doesn't print anything which needs complex interpretation (not intended for humans). But in general this point is valid - though fixing the output of the command to keep it all on one line would also be a useful thing to do, regardless of anything else. kre
Re: Idea: jobs(1) -i to print only :%ID:s
On Thu, Nov 9, 2023, 11:08 PM alex xmb sw ratchev wrote: > > > On Thu, Nov 9, 2023, 10:56 PM Greg Wooledge wrote: > >> On Thu, Nov 09, 2023 at 10:17:35PM +0100, Andreas Schwab wrote: >> > On Nov 09 2023, Greg Wooledge wrote: >> > >> > > re='^\[([0-9]+)\]' >> > > jobspecs=() >> > > while IFS= read -r line; do >> > > if [[ $line =~ $re ]]; then >> > > jobspecs+=( "%${BASH_REMATCH[1]}" ) >> > > fi >> > > done < <(jobs -l) >> > >> > That fails for multi-line commands that happen to contain matches for >> > re. >> > >> > $ (sleep 100; printf $'\n[100]\n') & >> >> Fair enough. I believe *nothing* would work in that case; the output of >> "jobs -l" cannot be safely parsed in its current form. >> >> Adding a NUL-delimited output option might work around that, but if we're >> modifying the jobs builtin, we might as well just add the -i or -j option >> instead. >> > > ther'd be few different values for seps , i think ifs is nearly none , so > , one is per element , one per record > others may also exist > so just two constant opts to align extend usage > i d have a half example about such formatting for printf ( pre ) ( sep for 2+ elements ) ( elem pre ( also elem N pre ) ) $elem ( elem stu or and N th ) ( end ) missing some terms also .. >
Re: Idea: jobs(1) -i to print only :%ID:s
On Thu, Nov 9, 2023, 10:56 PM Greg Wooledge wrote: > On Thu, Nov 09, 2023 at 10:17:35PM +0100, Andreas Schwab wrote: > > On Nov 09 2023, Greg Wooledge wrote: > > > > > re='^\[([0-9]+)\]' > > > jobspecs=() > > > while IFS= read -r line; do > > > if [[ $line =~ $re ]]; then > > > jobspecs+=( "%${BASH_REMATCH[1]}" ) > > > fi > > > done < <(jobs -l) > > > > That fails for multi-line commands that happen to contain matches for > > re. > > > > $ (sleep 100; printf $'\n[100]\n') & > > Fair enough. I believe *nothing* would work in that case; the output of > "jobs -l" cannot be safely parsed in its current form. > > Adding a NUL-delimited output option might work around that, but if we're > modifying the jobs builtin, we might as well just add the -i or -j option > instead. > ther'd be few different values for seps , i think ifs is nearly none , so , one is per element , one per record others may also exist so just two constant opts to align extend usage >
Re: Idea: jobs(1) -i to print only :%ID:s
On Thu, Nov 09, 2023 at 10:17:35PM +0100, Andreas Schwab wrote: > On Nov 09 2023, Greg Wooledge wrote: > > > re='^\[([0-9]+)\]' > > jobspecs=() > > while IFS= read -r line; do > > if [[ $line =~ $re ]]; then > > jobspecs+=( "%${BASH_REMATCH[1]}" ) > > fi > > done < <(jobs -l) > > That fails for multi-line commands that happen to contain matches for > re. > > $ (sleep 100; printf $'\n[100]\n') & Fair enough. I believe *nothing* would work in that case; the output of "jobs -l" cannot be safely parsed in its current form. Adding a NUL-delimited output option might work around that, but if we're modifying the jobs builtin, we might as well just add the -i or -j option instead.
Re: Idea: jobs(1) -i to print only :%ID:s
On Thu, Nov 9, 2023, 10:18 PM Andreas Schwab wrote: > On Nov 09 2023, Greg Wooledge wrote: > > > re='^\[([0-9]+)\]' > > jobspecs=() > > while IFS= read -r line; do > > if [[ $line =~ $re ]]; then > > jobspecs+=( "%${BASH_REMATCH[1]}" ) > > fi > > done < <(jobs -l) > > That fails for multi-line commands that happen to contain matches for > re. > > $ (sleep 100; printf $'\n[100]\n') & > a suggestion for the future , that bash coding keywords have own isf osf var following , so i can have null or other separated , by code builtins .. -- > Andreas Schwab, sch...@linux-m68k.org > GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1 > "And now for something completely different." > >
Re: Idea: jobs(1) -i to print only :%ID:s
Date:Thu, 09 Nov 2023 21:04:28 +0100 From:Steffen Nurpmeso Message-ID: <20231109200428.8g9lz%stef...@sdaoden.eu> | ash(1) and busybox ash(1) do not even support jobs -l in a function (yet). That seems unlikely, ash based shells mostly don't care whether the commands they're running are in a function or not, except for those few commands for which that is important (like return, local, etc). Are you sure that you're not seeing the effects of running jobs in a subshell environment (in a command substitution) - where no jobs have yet been created in that environment. Modern shells allow jobs (like trap) there, as a way to get the parent shell's jobs (or traps), but even now (in the latest drafts) POSIX does not require that jobs works that way (it does for trap, in very limited cases). kre
Re: Idea: jobs(1) -i to print only :%ID:s
On Nov 09 2023, Greg Wooledge wrote: > re='^\[([0-9]+)\]' > jobspecs=() > while IFS= read -r line; do > if [[ $line =~ $re ]]; then > jobspecs+=( "%${BASH_REMATCH[1]}" ) > fi > done < <(jobs -l) That fails for multi-line commands that happen to contain matches for re. $ (sleep 100; printf $'\n[100]\n') & -- Andreas Schwab, sch...@linux-m68k.org GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1 "And now for something completely different."
Re: Idea: jobs(1) -i to print only :%ID:s
Greg Wooledge wrote in : |On Thu, Nov 09, 2023 at 08:09:23PM +0100, Steffen Nurpmeso wrote: |> j() { |> local j= a=${AWK:-awk} |> [ $# -gt 0 ] && j='&& $2 !~ /(^| )('$(echo "$@" | tr ' ' '|')')( \ |> |$)/' |> j=$(jobs -l | $a -F '[][]' '/^[[]/'"$j"'{print "%" $2}{next}') |> echo $j |>} | |Classic code injection vulnerability. Well this is for me on my command line. ash(1) and busybox ash(1) do not even support jobs -l in a function (yet). (Where??) |What are we even parsing? Start with the input: | |unicorn:~$ sleep 5 & |[1] 849028 |unicorn:~$ jobs -l |[1]+ 849028 Running sleep 5 & | |OK, so you wanted to strip the "1" from "[1]" and turn that into "%1", |yes? That shouldn't be terribly hard in pure bash. | |re='^\[([0-9]+)\]' |jobspecs=() |while IFS= read -r line; do |if [[ $line =~ $re ]]; then This is indeed a nice approach. I have now spend over an hour stupid me, and have no more time to extend this to filter out the unwanted jobs, but i copy your thing over to my ~/.profile for a future full implementation! (Likely selectively after testing which shells actually do support this syntax, ie ksh and such.) |jobspecs+=( "%${BASH_REMATCH[1]}" ) |fi |done < <(jobs -l) | |Wrap that in a function with local declarations, etc. Thanks! Ciao, --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
Re: Idea: jobs(1) -i to print only :%ID:s
On Thu, Nov 9, 2023, 8:24 PM Greg Wooledge wrote: > On Thu, Nov 09, 2023 at 08:09:23PM +0100, Steffen Nurpmeso wrote: > > j() { > > local j= a=${AWK:-awk} > > [ $# -gt 0 ] && j='&& $2 !~ /(^| )('$(echo "$@" | tr ' ' '|')')( > |$)/' > > j=$(jobs -l | $a -F '[][]' '/^[[]/'"$j"'{print "%" $2}{next}') > > echo $j > > } > > Classic code injection vulnerability. > > What are we even parsing? Start with the input: > > unicorn:~$ sleep 5 & > [1] 849028 > unicorn:~$ jobs -l > [1]+ 849028 Running sleep 5 & > > OK, so you wanted to strip the "1" from "[1]" and turn that into "%1", > yes? That shouldn't be terribly hard in pure bash. > > re='^\[([0-9]+)\]' > jobspecs=() > while IFS= read -r line; do > if [[ $line =~ $re ]]; then > jobspecs+=( "%${BASH_REMATCH[1]}" ) > fi > done < <(jobs -l) > sleep 500h & sleep 400h & ~ $ s=7s jid=( ) jpid=( ) ; while IFS=$'\n' j=( $( jobs -l ) ) je=${#j[*]} IFS=$' \t\n' ; do ji=-1 ; while (( ++ji < je )) ; do t=( ${j[ji]} ) jid+=( "${t//[^0-9]}" ) jpid+=( "${t[1]}" ) ; done ; declare -p j{e,{,p}id} ; sleep "$s" ; done declare -- je="2" declare -a jid=([0]="1" [1]="2") declare -a jpid=([0]="21003" [1]="21009") Wrap that in a function with local declarations, etc. > >
Re: Idea: jobs(1) -i to print only :%ID:s
On Thu, Nov 9, 2023, 8:41 PM alex xmb sw ratchev wrote: > > > On Thu, Nov 9, 2023, 8:36 PM Steffen Nurpmeso wrote: > >> alex xmb sw ratchev wrote in >> : >> ... >> |> So i did that (what a mess -- does anyone know how i can create an >> |> awk regular expression where parts of the expression is a variable >> |> that should be expanded? ugh! what do i know??): >> | >> |awk -v var1='cont ent' -vv2="$other' ' { code } ' >> | >> |keep in mind that mass spawning of any bin is , when its done massley , >> |very out .. >> >> i fail to see what this has to do with my problem. >> >> |also var so awk processes some \esc caracters >> |to cleanly insert data , either use gawk ENVIRON["varname'] >> |or via alternative fd or as part of file parse things >> >> |my='a b c' >> |# one line string >> |awk 3<<<"$my thing' BEGIN { f = "/dev/fd/3" ; getline v > } >> |other main code here ' >> >> i am still wondering. >> >> |foo=content >> |export foo >> |or foo=$foo gawk .. >> |gawk -vv=foo ' BEGIN { v = ENVIRON[ v ] } other code ' >> |same as v = ENVIRON[ "v" ] or "varname" >> >> wow. >> >> |to match in string , thers two ways , one is exact text match , the >> other >> |is regex >> | >> |if u /foo/ thats a regex >> >> really? >> >> |$0 ~ "foo" >> | >> |tx=" my text " >> |if ( $0 ~ "pre" tx "stu" ) { ye } >> >> this does not work the way you think maybe? >> I surely was there myself. >> >> |thers additional stuff to say containing substr() and match() , and some >> >> even with match() not (in a global match line). >> >> |others >> | >> |#exact >> |etx = " exact " >> |if ( index( $0 , etx ) ) { ye } >> |if ( index( $0 , "pre" etx "stu" ) ) { ye } >> >> i am really impressed. >> But that did not work out. >> > > can u detail ur case some > i suggest using index > if u match or ~ u regex > means ur input s gotta get regex char escaped > unless u have a very special reason , use index > and not care about awk var \esc seq expandment > at least when have simple strings > > eg > > m=bar txt=' foo > bar > bla ' > awk -vm="$m" ' index( $0 , m ) ' > sorry missed again a detail awk -vm="$m" ' index( $0 , m ) ' <<<"$txt" should return the bar line > ' bar ' would also match > ' bar ' of course not > > --steffen >> | >> |Der Kragenbaer,The moon bear, >> |der holt sich munter he cheerfully and one by one >> |einen nach dem anderen runter wa.ks himself off >> |(By Robert Gernhardt) >> >
Re: Idea: jobs(1) -i to print only :%ID:s
On Thu, Nov 9, 2023, 8:36 PM Steffen Nurpmeso wrote: > alex xmb sw ratchev wrote in > : > ... > |> So i did that (what a mess -- does anyone know how i can create an > |> awk regular expression where parts of the expression is a variable > |> that should be expanded? ugh! what do i know??): > | > |awk -v var1='cont ent' -vv2="$other' ' { code } ' > | > |keep in mind that mass spawning of any bin is , when its done massley , > |very out .. > > i fail to see what this has to do with my problem. > > |also var so awk processes some \esc caracters > |to cleanly insert data , either use gawk ENVIRON["varname'] > |or via alternative fd or as part of file parse things > > |my='a b c' > |# one line string > |awk 3<<<"$my thing' BEGIN { f = "/dev/fd/3" ; getline v |other main code here ' > > i am still wondering. > > |foo=content > |export foo > |or foo=$foo gawk .. > |gawk -vv=foo ' BEGIN { v = ENVIRON[ v ] } other code ' > |same as v = ENVIRON[ "v" ] or "varname" > > wow. > > |to match in string , thers two ways , one is exact text match , the other > |is regex > | > |if u /foo/ thats a regex > > really? > > |$0 ~ "foo" > | > |tx=" my text " > |if ( $0 ~ "pre" tx "stu" ) { ye } > > this does not work the way you think maybe? > I surely was there myself. > > |thers additional stuff to say containing substr() and match() , and some > > even with match() not (in a global match line). > > |others > | > |#exact > |etx = " exact " > |if ( index( $0 , etx ) ) { ye } > |if ( index( $0 , "pre" etx "stu" ) ) { ye } > > i am really impressed. > But that did not work out. > can u detail ur case some i suggest using index if u match or ~ u regex means ur input s gotta get regex char escaped unless u have a very special reason , use index and not care about awk var \esc seq expandment at least when have simple strings eg m=bar txt=' foo bar bla ' awk -vm="$m" ' index( $0 , m ) ' should return the bar line ' bar ' would also match ' bar ' of course not --steffen > | > |Der Kragenbaer,The moon bear, > |der holt sich munter he cheerfully and one by one > |einen nach dem anderen runter wa.ks himself off > |(By Robert Gernhardt) >
Re: Idea: jobs(1) -i to print only :%ID:s
alex xmb sw ratchev wrote in : ... |> So i did that (what a mess -- does anyone know how i can create an |> awk regular expression where parts of the expression is a variable |> that should be expanded? ugh! what do i know??): | |awk -v var1='cont ent' -vv2="$other' ' { code } ' | |keep in mind that mass spawning of any bin is , when its done massley , |very out .. i fail to see what this has to do with my problem. |also var so awk processes some \esc caracters |to cleanly insert data , either use gawk ENVIRON["varname'] |or via alternative fd or as part of file parse things |my='a b c' |# one line string |awk 3<<<"$my thing' BEGIN { f = "/dev/fd/3" ; getline v
Re: Idea: jobs(1) -i to print only :%ID:s
On Thu, Nov 9, 2023, 8:10 PM Steffen Nurpmeso wrote: > Steffen Nurpmeso wrote in > <20231109181645.bocyg%stef...@sdaoden.eu>: > |Steffen Nurpmeso wrote in > | <20231109181107.bj0wl%stef...@sdaoden.eu>: > ||Steffen Nurpmeso wrote in > || <20231109011212.tc9hj%stef...@sdaoden.eu>: > || ... > ||Something like this that would be, adding JLIST_SPEC_ONLY and > ||jobs(1) -j. Just in case of interest. > | > |I mean some scripting on "jobs | wc -l" would do that, though. :( > > Nah, that would be wrong. > > |Maybe i should just write a function that builds the string > |necessary to do what i wanted with %* or "%1-2 %4" etc. > > So i did that (what a mess -- does anyone know how i can create an > awk regular expression where parts of the expression is a variable > that should be expanded? ugh! what do i know??): > awk -v var1='cont ent' -vv2="$other' ' { code } ' keep in mind that mass spawning of any bin is , when its done massley , very out .. also var so awk processes some \esc caracters to cleanly insert data , either use gawk ENVIRON["varname'] or via alternative fd or as part of file parse things my='a b c' # one line string awk 3<<<"$my thing' BEGIN { f = "/dev/fd/3" ; getline v local j= a=${AWK:-awk} > [ $# -gt 0 ] && j='&& $2 !~ /(^| )('$(echo "$@" | tr ' ' '|')')( |$)/' > j=$(jobs -l | $a -F '[][]' '/^[[]/'"$j"'{print "%" $2}{next}') > echo $j > } > > |Eh. Forget about it. > > Sorry for the noise. > > --steffen > | > |Der Kragenbaer,The moon bear, > |der holt sich munter he cheerfully and one by one > |einen nach dem anderen runter wa.ks himself off > |(By Robert Gernhardt) > >
Re: Idea: jobs(1) -i to print only :%ID:s
On Thu, Nov 09, 2023 at 08:09:23PM +0100, Steffen Nurpmeso wrote: > j() { > local j= a=${AWK:-awk} > [ $# -gt 0 ] && j='&& $2 !~ /(^| )('$(echo "$@" | tr ' ' '|')')( |$)/' > j=$(jobs -l | $a -F '[][]' '/^[[]/'"$j"'{print "%" $2}{next}') > echo $j > } Classic code injection vulnerability. What are we even parsing? Start with the input: unicorn:~$ sleep 5 & [1] 849028 unicorn:~$ jobs -l [1]+ 849028 Running sleep 5 & OK, so you wanted to strip the "1" from "[1]" and turn that into "%1", yes? That shouldn't be terribly hard in pure bash. re='^\[([0-9]+)\]' jobspecs=() while IFS= read -r line; do if [[ $line =~ $re ]]; then jobspecs+=( "%${BASH_REMATCH[1]}" ) fi done < <(jobs -l) Wrap that in a function with local declarations, etc.
Re: Idea: jobs(1) -i to print only :%ID:s
Steffen Nurpmeso wrote in <20231109181645.bocyg%stef...@sdaoden.eu>: |Steffen Nurpmeso wrote in | <20231109181107.bj0wl%stef...@sdaoden.eu>: ||Steffen Nurpmeso wrote in || <20231109011212.tc9hj%stef...@sdaoden.eu>: || ... ||Something like this that would be, adding JLIST_SPEC_ONLY and ||jobs(1) -j. Just in case of interest. | |I mean some scripting on "jobs | wc -l" would do that, though. :( Nah, that would be wrong. |Maybe i should just write a function that builds the string |necessary to do what i wanted with %* or "%1-2 %4" etc. So i did that (what a mess -- does anyone know how i can create an awk regular expression where parts of the expression is a variable that should be expanded? ugh! what do i know??): j() { local j= a=${AWK:-awk} [ $# -gt 0 ] && j='&& $2 !~ /(^| )('$(echo "$@" | tr ' ' '|')')( |$)/' j=$(jobs -l | $a -F '[][]' '/^[[]/'"$j"'{print "%" $2}{next}') echo $j } |Eh. Forget about it. Sorry for the noise. --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
Re: Idea: jobs(1) -i to print only :%ID:s
On Thu, Nov 9, 2023, 7:21 PM alex xmb sw ratchev wrote: > > > On Thu, Nov 9, 2023, 7:17 PM Steffen Nurpmeso wrote: > >> Steffen Nurpmeso wrote in >> <20231109181107.bj0wl%stef...@sdaoden.eu>: >> |Steffen Nurpmeso wrote in >> | <20231109011212.tc9hj%stef...@sdaoden.eu>: >> | ... >> |Something like this that would be, adding JLIST_SPEC_ONLY and >> |jobs(1) -j. Just in case of interest. >> >> I mean some scripting on "jobs | wc -l" would do that, though. :( >> Maybe i should just write a function that builds the string >> necessary to do what i wanted with %* or "%1-2 %4" etc. >> Eh. Forget about it. >> >> Ciao! >> > > jobs wc is > > j=( $( jobs -p ) ) > jc=${#j[*]} or ${ .. > > i think its with ' kinds ' cooperative > > greets > > -nlists only processes that have changed status since the > last > notification > -plists process IDs only > -rrestrict output to running jobs > -srestrict output to stopped jobs > > --steffen >> | >> |Der Kragenbaer,The moon bear, >> |der holt sich munter he cheerfully and one by one >> |einen nach dem anderen runter wa.ks himself off >> |(By Robert Gernhardt) >> >> >>
Re: Idea: jobs(1) -i to print only :%ID:s
On Thu, Nov 9, 2023, 7:17 PM Steffen Nurpmeso wrote: > Steffen Nurpmeso wrote in > <20231109181107.bj0wl%stef...@sdaoden.eu>: > |Steffen Nurpmeso wrote in > | <20231109011212.tc9hj%stef...@sdaoden.eu>: > | ... > |Something like this that would be, adding JLIST_SPEC_ONLY and > |jobs(1) -j. Just in case of interest. > > I mean some scripting on "jobs | wc -l" would do that, though. :( > Maybe i should just write a function that builds the string > necessary to do what i wanted with %* or "%1-2 %4" etc. > Eh. Forget about it. > > Ciao! > jobs wc is j=( $( jobs -p ) ) or ${ .. i think its with ' kinds ' cooperative greets -nlists only processes that have changed status since the last notification -plists process IDs only -rrestrict output to running jobs -srestrict output to stopped jobs --steffen > | > |Der Kragenbaer,The moon bear, > |der holt sich munter he cheerfully and one by one > |einen nach dem anderen runter wa.ks himself off > |(By Robert Gernhardt) > >
Re: Idea: jobs(1) -i to print only :%ID:s
Steffen Nurpmeso wrote in <20231109181107.bj0wl%stef...@sdaoden.eu>: |Steffen Nurpmeso wrote in | <20231109011212.tc9hj%stef...@sdaoden.eu>: | ... |Something like this that would be, adding JLIST_SPEC_ONLY and |jobs(1) -j. Just in case of interest. I mean some scripting on "jobs | wc -l" would do that, though. :( Maybe i should just write a function that builds the string necessary to do what i wanted with %* or "%1-2 %4" etc. Eh. Forget about it. Ciao! --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
Re: Idea: jobs(1) -i to print only :%ID:s
Steffen Nurpmeso wrote in <20231109011212.tc9hj%stef...@sdaoden.eu>: ... Something like this that would be, adding JLIST_SPEC_ONLY and jobs(1) -j. Just in case of interest. diff --git a/builtins/jobs.def b/builtins/jobs.def index 1ce098d08b..989a78079e 100644 --- a/builtins/jobs.def +++ b/builtins/jobs.def @@ -23,13 +23,14 @@ $PRODUCES jobs.c $BUILTIN jobs $FUNCTION jobs_builtin $DEPENDS_ON JOB_CONTROL -$SHORT_DOC jobs [-lnprs] [jobspec ...] or jobs -x command [args] +$SHORT_DOC jobs [-jlnprs] [jobspec ...] or jobs -x command [args] Display status of jobs. Lists the active jobs. JOBSPEC restricts output to that job. Without options, the status of all active jobs is displayed. Options: + -j lists only jobspecs -l lists process IDs in addition to the normal information -n lists only processes that have changed status since the last notification @@ -90,10 +91,13 @@ jobs_builtin (list) state = JSTATE_ANY; reset_internal_getopt (); - while ((opt = internal_getopt (list, "lpnxrs")) != -1) + while ((opt = internal_getopt (list, "jlpnxrs")) != -1) { switch (opt) { + case 'j': + form = JLIST_SPEC_ONLY; + break; case 'l': form = JLIST_LONG; break; diff --git a/doc/bash.1 b/doc/bash.1 index 55c562208a..8dc34a00d7 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -9150,7 +9150,7 @@ error occurs while reading or writing the history file, an invalid history expansion supplied as an argument to \fB\-p\fP fails. .RE .TP -\fBjobs\fP [\fB\-lnprs\fP] [ \fIjobspec\fP ... ] +\fBjobs\fP [\fB\-jlnprs\fP] [ \fIjobspec\fP ... ] .PD 0 .TP \fBjobs\fP \fB\-x\fP \fIcommand\fP [ \fIargs\fP ... ] @@ -9160,6 +9160,9 @@ meanings: .RS .PD 0 .TP +.B \-j +List only the \fIjobspec\fPs. +.TP .B \-l List process IDs in addition to the normal information. diff --git a/jobs.c b/jobs.c index 45869dd819..b56cecccb3 100644 --- a/jobs.c +++ b/jobs.c @@ -2037,6 +2037,13 @@ pretty_print_job (job_index, format, stream) { register PROCESS *p; + /* Format only jobspec? */ + if (format == JLIST_SPEC_ONLY) +{ + fprintf (stream, "%%%d\n", job_index + 1); + return; +} + /* Format only pid information about the process group leader? */ if (format == JLIST_PID_ONLY) { diff --git a/jobs.h b/jobs.h index 276204f0c7..5d1cc43d1f 100644 --- a/jobs.h +++ b/jobs.h @@ -32,8 +32,9 @@ #define JLIST_STANDARD 0 #define JLIST_LONG 1 #define JLIST_PID_ONLY 2 -#define JLIST_CHANGED_ONLY 3 -#define JLIST_NONINTERACTIVE 4 +#define JLIST_SPEC_ONLY 3 +#define JLIST_CHANGED_ONLY 4 +#define JLIST_NONINTERACTIVE 5 /* I looked it up. For pretty_print_job (). The real answer is 24. */ #define LONGEST_SIGNAL_DESC 24 --steffen | |Der Kragenbaer,The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)