Re: Strange behavior with job control
Christoph Dittmann writes: > Why is "sleep 5" still running in the second case even though the job > received SIGTERM and is known to the job control as "terminated"? Try adding "ps f" before the wait command to see the difference in how bash executes the two cases. In the case without the braces the subshell replaces itself with the sleep command, which is what is then killed. In the other case with the braces the subshell executes the sleep as a subprocess and waits for it to terminate. The kill command then kills the subshell but the sleep command continues. If you want to kill the whole background job you need to enable job control (set -m) and call kill with the job specifier instead (kill %2 in this case). > How can the wait call affect a job it's not supposed to wait for? It's a simple race. You may not give the subshell enough time to acutally execute the sleep command. Andreas. -- Andreas Schwab, sch...@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different."
Re: Strange behavior with job control
On 07/27/2010 12:05 PM, Andreas Schwab wrote: > If you want to kill the whole background job you need to enable job > control (set -m) and call kill with the job specifier instead (kill %2 > in this case). > >> How can the wait call affect a job it's not supposed to wait for? > > It's a simple race. You may not give the subshell enough time to > acutally execute the sleep command. Hi Andreas, thanks a lot. I suspected it might be something simple like that. "set -m" solved the problem for me. What I was going for was a script which executes another command with a timeout. This is what I now came up with: #!/bin/bash if [[ $# -lt 2 ]]; then echo "Usage: $(basename $0) timeout_in_seconds commandline..." echo "Runs the command and sends SIGTERM to the child after the specified timeout." exit 0 fi # Enable job control. set -mb TIMEOUT="$1" shift # Use SIGUSR1 to interrupt the wait call. trap ':' USR1 # Run the desired command. "$@" & # Suppress any output from now on. exec &>/dev/null # Run the watchdog. { sleep $TIMEOUT ; kill -USR1 $$; } & # Give the command a chance to complete. wait %1 EXIT_STATUS=$? # Send SIGTERM to the watchdog and the command. If a job is not # running, the kill has no effect. kill %2 kill %1 exit $EXIT_STATUS It works in all my test cases. Because I'm still learning to write bash scripts, I'd be very interested to know if there are any obvious blunders in the way I did it (or more subtle mistakes). Also, is there a more elegant way to achieve the same effect? I thought running a process with a time limit would not be such an unlikely thing to do. Christoph
Re: Strange behavior with job control
On 07/27/2010 05:44 AM, Christoph Dittmann wrote: > What I was going for was a script which executes another command with a > timeout. If you can assume the presence of GNU coreutils, use timeout(1). Much nicer for this particular task. Otherwise, I did not review your script for accuracy. -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: Strange behavior with job control
On 07/27/2010 02:05 PM, Eric Blake wrote: > On 07/27/2010 05:44 AM, Christoph Dittmann wrote: >> What I was going for was a script which executes another command with a >> timeout. > > If you can assume the presence of GNU coreutils, use timeout(1). Much > nicer for this particular task. Thanks, I'll look into this. OK, it looks like timeout(1) is in coreutils starting with version 7.5-1, and unfortunately Ubuntu 10.04 only offers coreutils-7.4-2 with timeout in a separate package. According to the manpage, timeout does precisely what I need. I'll definitely remember that program, thanks. It's probably a cleaner way than implementing a bash script to do the same task manually. Christoph
Re: When to use printf instead of echo?
On Mon, Jul 26, 2010 at 04:27:30PM -0500, Peng Yu wrote: > Could you > please let me know when to use printf instead of echo? There is never any need to use echo. printf does everything echo does, and does it better -- but people are comfortable with echo, because it's simple, and they've been trained by 15 years of legacy scripts that used it. > In particular, I want to print a string that has single quote, double > quote and dollar character. printf "%s\n" "$mystring" It makes no difference what the contents of the variable are. > I could use " to enclose such string and > add '\' to escape " and $ in the string. Oh, you mean to express a string constant in the code? That has nothing at all to do with the commands you give it to. mystring='whatever'$'whatever'"whatever"\w\h\a\t\e\v\e\r Do whatever it takes. Concatenate multiple quoting styles as needed. Back to your specific complaint: > In particular, I want to print a string that has single quote, double > quote and dollar character. Meaning "I want to create a string constant that contains a single quote, a double quote and a dollar sign." Style 1: \'\"\$ Style 2: \''"$' Style 3: "'\"\$" Style 4: $'\'"$' etc. At this point it's a matter of personal choice. Pick whichever style looks least ugly to you. There are an infinite number of ways you could write this (if you discard the ways that simply append '' and the like to the constant for no reason, it becomes finite, but I have no intention of counting them all).
Re: Strange behavior with job control
On Tue, Jul 27, 2010 at 01:44:26PM +0200, Christoph Dittmann wrote: > What I was going for was a script which executes another command with a > timeout. http://mywiki.wooledge.org/BashFAQ/068 http://mywiki.wooledge.org/XyProblem
Re: Strange behavior with job control
On 07/27/2010 02:35 PM, Greg Wooledge wrote: > On Tue, Jul 27, 2010 at 01:44:26PM +0200, Christoph Dittmann wrote: >> What I was going for was a script which executes another command with a >> timeout. > > http://mywiki.wooledge.org/BashFAQ/068 The process I want to put under the timeout does not offer a timeout setting by itself (see below). The bash script http://www.shelldorado.com/scripts/cmds/timeout lets the watchdog stay around long after the command has finished: $ ./timeout -t 60 echo done; sleep 1; ps aux | grep '[s]leep' done 100023115 0.0 0.0 9728 828 pts/1S15:00 0:00 sleep 60 timeout(1) looks like the way to go. The only thing I don't like is that it is not installed on a standard debian or ubuntu system. That's why I was hoping for a solution in bash. > http://mywiki.wooledge.org/XyProblem Oh, shame on me. :/ I can see how such a script looks like a really bad idea. Just for the background: I run "darcs pull" in a cronjob every few hours to mirror a darcs repository. If the darcs server happens to be offline or not answering properly, it can happen that "darcs pull" hangs for hours without doing anything. This happened only once so far and I couldn't reproduce the circumstances. However, it broke the cronjob because the hanging darcs process kept a lock in the local repository. Just to avoid this I wanted to place a (relatively high) timeout on "darcs pull" so that the repository is not locked indefinitely if something goes wrong. Christoph
Re: RFE -or- Howto?
Huh. Triple redirect... Thanks! On 7/26/2010 5:53 PM, Chet Ramey wrote: > On 7/26/10 6:25 PM, Linda Walsh wrote: >> I don't know if there's an easy way, but if not would you consider an >> RFE -- >> >> Is there a syntax for a mult-var assignment, ala: >> (a b c d)=(1 2 3 4) > > Yes. > > read a b c d <<<"1 2 3 4" > > Chet
crash when using associative array and integer variable
Repeated in the bash-4.0.38 and bash-4.1.7 by the script; #!/bin/bash typeset -Ai s y='*' z='[' s[$y]=1 s[$z]=2 (( s[$z] = s[$z] + ${s[$y]} )) (( s[$y] = s[$y] + ${s[$z]} )) [[ ${s[$y]} = 4 ]] && echo "ok" FIX: added check; diff -up bash-4.1/variables.c.Ai bash-4.1/variables.c --- bash-4.1/variables.c.Ai 2010-07-28 08:42:54.0 +0200 +++ bash-4.1/variables.c2010-07-28 08:43:17.0 +0200 @@ -2371,7 +2371,7 @@ bind_int_variable (lhs, rhs) #endif v = bind_variable (lhs, rhs, 0); - if (isint) + if (isint && v) VSETATTR (v, att_integer); return (v); RR