You can stop and put your job in background while it's running using ctrl+z. Then you can kill your job with:
$ kill %1
Where [1] is your job number.
Answer from Jem on Stack ExchangeYou can stop and put your job in background while it's running using ctrl+z. Then you can kill your job with:
$ kill %1
Where [1] is your job number.
Check the exit status of the command. If the command was terminated by a signal the exit code will be 128 + the signal number. From the GNU online documentation for bash:
For the shell’s purposes, a command which exits with a zero exit status has succeeded. A non-zero exit status indicates failure. This seemingly counter-intuitive scheme is used so there is one well-defined way to indicate success and a variety of ways to indicate various failure modes. When a command terminates on a fatal signal whose number is N, Bash uses the value 128+N as the exit status.
POSIX also specifies that the value of a command that terminated by a signal is greater than 128, but does not seem to specify its exact value like GNU does:
The exit status of a command that terminated because it received a signal shall be reported as greater than 128.
For example if you interrupt a command with control-C the exit code will be 130, because SIGINT is signal 2 on Unix systems. So:
while [ 1 ]; do COMMAND; test $? -gt 128 && break; done
Videos
How do you make an infinite loop in Bash?
How do I exit a Bash loop?
How do you break an infinite loop?
With the & inside the loop it will start a new process in the background and as fast as it can do it again without waiting for the first process to end. Instead I think you want to put the loop into the background, so put the & on the loop itself like
while /bin/true; do
something_in_the_background
done &
# more stuff
while : ; do something ; done &
Earlier Bourne shells didn't have
trueandfalseas built-in commands.truewas instead simply aliased to:, andfalseto something likelet 0.&at the end of the line backgrounds the process:is the null command, as described by "help :":No effect; the command does nothing. Exit Status: Always succeeds.
while true; do foo; sleep 2; done
By the way, if you type it as a multiline (as you are showing) at the command prompt and then call the history with arrow up, you will get it on a single line, correctly punctuated.
$ while true
> do
> echo "hello"
> sleep 2
> done
hello
hello
hello
^C
$ <arrow up> while true; do echo "hello"; sleep 2; done
It's also possible to use sleep command in while's condition. Making one-liner looking more clean imho.
while sleep 2; do echo thinking; done
How to run a
infinite_number_loopin bash?
The easy way: while :; do ... done:
let i=0
while :; do
let i++
date +%Y-%m-%d -d "$i day ago" >/dev/null 2>&1 || { echo $i && exit 1; }
done
If I run this loop in terminal in my local machine, is there any issue?
Not until you realize you wasted too much time on this.
Not an infinite loop, but a better way to find the actual limit of date:
#!/bin/bash
j=$((1<<61))
i=0
while ((j>0)); do
if date +'%Y-%m-%d' -d "$((i+j)) days ago" >/dev/null 2>&1; then
((i+=j)) ; # printf 'running i %d 0x%x\n' "$i"{,}
else
((j>>=1)); # printf 'new j %d 0x%x\n' "$j"{,}
fi
((k++))
# ((k%10)) || printf 'still running %d 0x%x %d %d' "$i"{,} "$j" "$k"
done
printf "final value of limit %d 0x%x in %d loops\n" "$i"{,} "$k"
That will find the limit of date to be:
final value of limit 2147483649 0x80000001 in 64 loops
Remove the comment character # to see how that is done.
It is not a 32 bit number.
That seem to be close to a 32 bit number:
$ printf '%d\n%d\n' "$(( (1<<31) + 1 ))" "0x80000001"
2147483649
2147483649
In fact, is 2**31 + the day number of the month.
If we try with the last day in December (change line 5 in the script above):
date +'%Y-%m-%d' -d "2017-12-31 $((i+j)) days ago"
We get:
final value of limit 2147483679 0x8000001f in 68 loops
That's 31 above 2**31:
$ printf '%d\n%d\n' "$(( (2**31) + 31 ))" "0x8000001f"
2147483679
2147483679
It is also affected by the time zone.
Arithmetic notes
The max value for a shell integer is i less than 2 raised to 63:
$ echo $(( (2**63) - 1 ))
9223372036854775807
We can get the decimal and hexadecimal representation with:
$ printf '%d %x\n' "$(( (2**63) - 1 ))"{,}
9223372036854775807 7fffffffffffffff
That's the maximum number representable in a signed integer of 64 bits (if your system is 64 bits, of course). The next number (just add one) will wrap around (overflow) to a negative number:
$ echo $(( (2**63) ))
-9223372036854775808
$ printf '%d %x\n' "$(( (2**63) ))"{,}
-9223372036854775808 8000000000000000
Which happens to be the most negative number for signed 64 bit integer.
But a faster way to get the same result is using left shift, which does the same as multiplying a number by two:
$ printf '%d %x\n' "$(( (1<<63) - 1 ))"{,}
9223372036854775807 7fffffffffffffff