从命令行接受数字并执行函数直到数字为1的Bash脚本
我正在尝试制作一个bash脚本,该脚本从命令行接收一个数字(介于1和50之间)。如果该数字为偶数,则将其除以2;如果该数字为奇数,则将其乘以3并加1。然后,数字通过函数返回,直到达到数字1。这是我到目前为止所拥有的从命令行接受数字并执行函数直到数字为1的Bash脚本,bash,Bash,我正在尝试制作一个bash脚本,该脚本从命令行接收一个数字(介于1和50之间)。如果该数字为偶数,则将其除以2;如果该数字为奇数,则将其乘以3并加1。然后,数字通过函数返回,直到达到数字1。这是我到目前为止所拥有的 #!/bin/bash //this looks to see if the command line argument, $1, is between 1 and 50 if ["$1" -gt 1 ] && [ "$1" -lt 50] then //if $1
#!/bin/bash
//this looks to see if the command line argument, $1, is between 1 and 50
if ["$1" -gt 1 ] && [ "$1" -lt 50]
then
//if $1 is between 1 and 50, it goes into a for loop when it looks to see if it is even or odd. It keeps going until the number 1 is reached, and prints out each number until then
for i in $1; do
//if $1 is even
if [i%2 -eq 0]
then
i/2 == i
echo "i,"
//if $1 is even
else
3*i+1 == i
echo "i,"
fi
done
fi
当我运行代码时,我得到一个错误
$ ./q1.sh 5
./q1.sh: line 3: [5: command not found
我在网上查看了错误的含义,但找不到答案。有人能帮帮我吗。除了在
[i%2-eq 0]
和[“$1”-lt 50]
中缺少空格外,您的算术用法不正确,还有几个变量赋值问题。您需要将算术结果分配给手头的值。表单是var=value
,而不是value==var
对于如何在bash中执行算术,您有3种选择。旧的newval=$(expr i/2)
或让newval=“$i”/2
或newval=$((i/2))
:
清理脚本时,可以执行以下操作:
if [ "$1" -gt 1 ] && [ "$1" -lt 50 ]
then
for i in $1; do
//if $i is even
if (( i % 2 == 0 ))
then
newvar=$((i / 2))
echo "$newvar,"
//if $i is odd
else
newvar=$((3 * i + 1))
echo "$newvar,"
fi
done
fi
注意,虽然您可以乘法并重新分配循环增量i
,但最好将结果分配给新变量,例如某些newvar
请注意:
newvar=$((i / 2))
及
看起来您还打算:
if [ "${#1}" -gt 1 ] && [ "${#1}" -lt 50 ]
要检查给定的字符数是否介于1
和50
之间,否则,您的为i,单位为$1;do
没有多大意义。如果您只是测试值而不是字符数,请将的全部去掉:
if [ "$1" -gt 1 -a "$1" -lt 50 ]
then
val="$1" ## assign positinal parameter to variable
## if $val is even ## to avoid subtleties in syntax
if (( val % 2 == 0 ))
then
newvar=$((val / 2))
echo "$newvar,"
## if $val is odd
else
newvar=$((3 * val + 1))
echo "$newvar,"
fi
fi
备选方案
如果我弄清楚你想做什么,那么你可以考虑这样做:
#!/bin/bash
declare -i val
if [ "$1" -gt 1 -a "$1" -lt 50 ]; then
val="$1" # assign val=$1
while ((val > 0)); do # loop for val > 0
if ((val > 1)); then # set output format
fmt="%d,"
else
fmt="%d"
fi
if ((val % 2 == 0)) # if $val is even
then
n=$((val / 2))
else # if $val is even
n=$((val * 3 + 1))
fi
printf "$fmt" "$n"
((val--)) # decrement val
done
else
printf "input value not between 1 and 50\n"
fi
printf "\n"
示例使用/输出
$ bash ql.sh 10
5,28,4,22,3,16,2,10,1,4
或者,使用复合命令以更紧凑的形式重写:
除了在[i%2-eq 0]
和[“$1”-lt 50]
中缺少空格外,您的算术使用不正确,还存在一些变量赋值问题。您需要将算术结果分配给手头的值。表单是var=value
,而不是value==var
对于如何在bash中执行算术,您有3种选择。旧的newval=$(expr i/2)
或让newval=“$i”/2
或newval=$((i/2))
:
清理脚本时,可以执行以下操作:
if [ "$1" -gt 1 ] && [ "$1" -lt 50 ]
then
for i in $1; do
//if $i is even
if (( i % 2 == 0 ))
then
newvar=$((i / 2))
echo "$newvar,"
//if $i is odd
else
newvar=$((3 * i + 1))
echo "$newvar,"
fi
done
fi
注意,虽然您可以乘法并重新分配循环增量i
,但最好将结果分配给新变量,例如某些newvar
请注意:
newvar=$((i / 2))
及
看起来您还打算:
if [ "${#1}" -gt 1 ] && [ "${#1}" -lt 50 ]
要检查给定的字符数是否介于1
和50
之间,否则,您的为i,单位为$1;do
没有多大意义。如果您只是测试值而不是字符数,请将
的全部去掉:
if [ "$1" -gt 1 -a "$1" -lt 50 ]
then
val="$1" ## assign positinal parameter to variable
## if $val is even ## to avoid subtleties in syntax
if (( val % 2 == 0 ))
then
newvar=$((val / 2))
echo "$newvar,"
## if $val is odd
else
newvar=$((3 * val + 1))
echo "$newvar,"
fi
fi
备选方案
如果我弄清楚你想做什么,那么你可以考虑这样做:
#!/bin/bash
declare -i val
if [ "$1" -gt 1 -a "$1" -lt 50 ]; then
val="$1" # assign val=$1
while ((val > 0)); do # loop for val > 0
if ((val > 1)); then # set output format
fmt="%d,"
else
fmt="%d"
fi
if ((val % 2 == 0)) # if $val is even
then
n=$((val / 2))
else # if $val is even
n=$((val * 3 + 1))
fi
printf "$fmt" "$n"
((val--)) # decrement val
done
else
printf "input value not between 1 and 50\n"
fi
printf "\n"
示例使用/输出
$ bash ql.sh 10
5,28,4,22,3,16,2,10,1,4
或者,使用复合命令以更紧凑的形式重写:
仅根据您的要求,我将按以下方式解决此问题:
#!/bin/bash
# Assign positional parameter
num="$1"
if (( num > 1 && num < 50 )); then
while (( num != 1 )); do
if (( num % 2 == 0 )); then # Number is even
(( num /= 2)) # Compound assignment: same as num = num / 2
else # Number is odd
(( num = num * 3 + 1 ))
fi
printf "Number is %d\n" "$num"
done
fi
#/bin/bash
#指定位置参数
num=“$1”
如果((num>1&&num<50));然后
而((num!=1));做
如果((num%2==0));那么#数字是偶数
((num/=2))#复合赋值:与num=num/2相同
否则,数字是奇数
((num=num*3+1))
fi
printf“编号为%d\n”“$num”
完成
fi
这使得在条件和计算中大量使用算术表达式(…)
。事实上,我从来没有使用过测试构造[…]
。如果我使用它,我甚至可以在表达式中赋值,例如,((num=num*2))
而不是num=$((num*2))
注意while循环如何检查我们是否已经达到值1。您使用$1中的i的尝试它的方式只是将$1
分配给i
的一种(复杂的)方式,但循环只执行一次
代码中无法工作的内容
- 注释以
开头,而不是以/
开头
- 测试构造
[…]
需要空格:[“$1”-gt 1]
等
for
循环只将$1
分配给i
,没有其他分配
[i%2-等式0]
比较文本i%2
,而不是变量i
模2的结果;你需要[$((i%2))-eq 0]
,或者((i%2==0))
- 赋值
i/2==i
将尝试使用参数=
和i
执行命令i/2
,但几乎没有成功。您需要i=$((i/2))
或((i/=2))
echo“i,
只打印i,
。您需要回显“$i”,
- 有关赋值
3*i+1==i
,请参见上文
仅根据您的要求,我将按以下方式解决此问题:
#!/bin/bash
# Assign positional parameter
num="$1"
if (( num > 1 && num < 50 )); then
while (( num != 1 )); do
if (( num % 2 == 0 )); then # Number is even
(( num /= 2)) # Compound assignment: same as num = num / 2
else # Number is odd
(( num = num * 3 + 1 ))
fi
printf "Number is %d\n" "$num"
done
fi
#/bin/bash
#指定位置参数
num=“$1”
如果((num>1&&num<50));然后
而((num!=1));做
如果((num%2==0));那么#数字是偶数
((num/=2))#复合赋值:与num=num/2相同
否则,数字是奇数
((num=num*3+1))
fi
printf“编号为%d\n”“$num”
完成
fi
这使得在条件和计算中大量使用算术表达式(…)
。事实上,我从来没有使用过测试构造[…]
。如果我使用它,我甚至可以在表达式中使用((num=num*2))而不是赋值