「how to "%" modulo in alpine linux or in ash shell」でググってもピンポイントでヒットしなかったので、自分のググラビリティとして。
TL; DR
Quote with
$((
))
instead of$[
]
ash/bash_compatible
#!/bin/sh
echo $(( $RANDOM % 10 ))
/app/tests # # Tested Alpine version (via Docker)
/app/tests # cat /etc/os-release | grep PRETTY
PRETTY_NAME="Alpine Linux v3.10"
/app/tests # # View sample script
/app/tests # cat sample.sh
#!/bin/sh
tmp_rand=$RANDOM
echo $tmp_rand
echo $(( $tmp_rand % 10 ))
echo $(($tmp_rand % 10))
echo $(( $tmp_rand % 10 + 1 ))
/app/tests # # Run in Ash shell
/app/tests # /bin/sh ./sample.sh
23095
5
5
6
/app/tests # # Run in Bash shell
/app/tests # /bin/bash ./sample.sh
9465
5
5
6
/app/tests #
If you get an error of "arithmetic expression: expecting primary: " ... "
", you are probably using a shell that does not support $RANDOM
. In that case consider using :-
substitution.
Example
# 12345 will be used if $RANDOM is empty or not defined. Thus, not random.
RANDOM=${RANDOM:-12345}
TS; DR
Ordinary way. Runs in Bash but not in ASH. (Not compatible)
sample1.sh
#!/bin/bash
time_sleep=$[ ( $RANDOM % 10 ) + 1 ]
echo "Sleeping ${time_sleep} seconds ..."
sleep "${time_sleep}"s
/app/tests # # Run in Ash shell (Fails)
/app/tests # /bin/sh ./sample1.sh
./sample.sh: line 3: syntax error: unexpected "("
/app/tests # # Run in Bash shell
/app/tests # /bin/bash ./sample1.sh
Sleeping 3 seconds ...
- View it online @ paiza.IO
Now, let's make it compatible between Bash and Ash.
sample2.sh
#!/bin/sh
time_sleep=$(( $RANDOM % 10 + 1 ))
echo "Sleeping ${time_sleep} seconds ..."
sleep "${time_sleep}"s
/app/tests # # Run in Bash
/app/tests # /bin/bash ./sample2.sh
Sleeping 8 seconds ...
/app/tests # # Run in Ash
/app/tests # /bin/sh ./sample2.sh
Sleeping 8 seconds ...
- View it online @ paiza.IO
VersionInfo
/app/tests # # Alpine Linux default shell
/app/tests # /bin/sh --help
/bin/sh --help
BusyBox v1.30.1 (2019-06-12 17:51:55 UTC) multi-call binary.
Usage: sh [-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]
Unix shell interpreter
/app/tests # # Install bash shell
/app/tests # apk --no-cache add bash
...
/app/tests # /bin/bash --version | grep version
GNU bash, version 5.0.0(1)-release (x86_64-alpine-linux-musl)
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
Reference(参考文献)
- Newbie question: modulo operator with negative operand, bug or feature? @ The UNIX and Linux Forums