You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shell脚本出现expr非整数参数错误,请求排查代码问题

Fixing the "expr: non-integer argument" Error in Your Shell Script

Hey there! Let's break down what's causing that frustrating error in your factorial sum script, and fix it up step by step.

First, let's look at your original code to spot the issues:

num=$1 sum=0; rn=0 less=0; fact=0 
while [ $num -gt 0 ] 
do 
    rn=`expr $num % 10` 
    num=`expr $num / 10` 
    while [ $rn -gt 1 ] 
    do 
        less=`expr %rn - 1`  # Here's a big problem!
        fact=`expr $rn \* less` 
        rn=`expr $rn - 1` 
    done 
    sum=`expr $sum + $fact` 
done 
echo $sum

Key Issues Causing the Error

  1. Incorrect Variable Reference
    The line less=expr %rn - 1`` uses %rn instead of $rn. Without the dollar sign, expr treats %rn as a literal string, not the integer value stored in the rn variable. That's exactly why you're getting the "non-integer argument" error.

  2. Uninitialized Factorial Variable
    You set fact=0 at the start, but factorial calculations start at 1 (e.g., 5! = 5×4×3×2×1). If you start with 0, every factorial result will be 0, and you'll never get the correct sum. Worse, you don't reset fact between calculating each digit's factorial—so old values will carry over and mess up subsequent calculations.

  3. Overwriting the Outer Loop's Variable
    Your inner loop modifies rn, which is the variable you're using in the outer loop to extract digits from num. This will throw off the outer loop's logic, causing it to process digits incorrectly.

Fixed Version of the Script

Here's the corrected code with explanations of each change:

num=$1
sum=0

while [ $num -gt 0 ]
do
    # Extract the last digit of num
    rn=$(expr $num % 10)
    # Remove the last digit from num
    num=$(expr $num / 10)
    
    # Reset fact to 1 for each new digit's factorial calculation
    fact=1
    # Use a temp variable to avoid messing with the outer loop's rn
    temp_rn=$rn
    
    while [ $temp_rn -gt 1 ]
    do
        # Correctly reference the temp_rn variable with $
        less=$(expr $temp_rn - 1)
        # Multiply current fact by temp_rn to build the factorial
        fact=$(expr $fact \* $temp_rn)
        # Decrement the temp variable for the next iteration
        temp_rn=$less
    done
    
    # Add the calculated factorial to the total sum
    sum=$(expr $sum + $fact)
done

echo $sum

What Changed?

  • Replaced %rn with $temp_rn to properly reference the variable's integer value, eliminating the expr error.
  • Added a temp_rn variable to handle the factorial calculation, so we don't overwrite the rn value used in the outer loop.
  • Reset fact=1 at the start of each digit's factorial calculation to ensure accurate results.
  • Switched to $(...) for command substitution (instead of backticks) — it's more readable and less prone to nesting issues, though backticks would still work if you prefer them.

Test this script with a number like 145 (a factorion, where the sum of the factorials of its digits equals the number itself) — it should output 145 as expected!

内容的提问来源于stack exchange,提问作者Richi Dubey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:27:30