Bash脚本无法识别函数问题排查及修复方案
解决Bash脚本中函数未被识别的问题
问题分析
你碰到的delete_snapshots: command not found报错,核心原因是Bash脚本是按顺序解析执行的——原脚本里你在调用delete_snapshots函数之后才定义它,导致执行到调用语句时,Bash还没读取到这个函数的定义,自然识别不了。
你的报错信息如下:
./delete_snapshots.sh
What AWS Account:
12345678910
Delete Snapshots in account: AWS Lab
./delete_snapshots.sh: line 14: delete_snapshots: command not found
原脚本的问题点
原脚本中函数定义放在了脚本末尾,而调用逻辑在前面,这就导致了调用时函数还未被加载:
#!/bin/bash echo "What AWS Account: "; read accountnumber declare -a arr=("12345678910" "109876543212") for i in "${arr[@]}" do if [ "$i" -eq 12345678910 ]; then aws_account="AWS Lab" aws_key="lab" aws_file="aws_lab_snapshots.txt" echo "Delete Snapshots in account: $aws_account" delete_snapshots # 这里调用函数,但函数还没定义 break elif [ "$i" -eq 109876543212 ]; then aws_account="AWS Billing" aws_key="bill" aws_file="aws_bill_snapshots.txt" echo "You are currently in account: $aws_account" delete_snapshots # 同样的问题 break else echo "Unkown account" fi done # 函数定义在调用之后,Bash无法提前识别 delete_snapshots(){ for i in $(cat $aws_file) do echo "*****************************************************************" echo "deleting snapshot: $i" aws ec2 delete-snapshot --snapshot-id=$i --profile=lab 2>&1 | sed -e 's/^An error occurred.*when calling the DeleteSnapshot operation: //' echo "*****************************************************************" echo; echo; echo; echo; echo sleep 5 echo "*****************************************************************" echo "Verify that snapshot: $i is gone:" aws ec2 describe-snapshots --snapshot-ids=$i --profile=lab 2>&1 | sed -e 's/^An error occurred.*when calling the DescribeSnapshots operation: //g' echo "*****************************************************************" echo; echo; echo; echo; echo done }
修复后的可运行脚本
把函数定义移到脚本最开头,同时做了几个关键优化让脚本更健壮:
#!/bin/bash delete_snapshots(){ for i in $(cat $aws_file) do echo "*****************************************************************" echo "deleting snapshot: $i" aws ec2 delete-snapshot --snapshot-id=$i --profile=$aws_key 2>&1 | sed -e 's/^An error occurred.*when calling the DeleteSnapshot operation: //' echo "*****************************************************************" echo; echo; echo; echo; echo sleep 5 echo "*****************************************************************" echo "Verify that snapshot: $i is gone:" aws ec2 describe-snapshots --snapshot-ids=$i --profile=$aws_key 2>&1 | sed -e 's/^An error occurred.*when calling the DescribeSnapshots operation: //g' echo "*****************************************************************" echo; echo; echo; echo; echo done } echo "What AWS Account: "; read accountnumber declare -a arr=("123456789101" "109876543212") for i in "${arr[@]}" do if [ "$i" -eq 123456789101 ]; then aws_account="AWS Lab" aws_key="lab" aws_file="source_files/aws_lab_snapshots.txt" echo "Delete Snapshots in account: $aws_account" delete_snapshots break elif [ "$i" -eq 109876543212 ]; then aws_account="AWS Billing" aws_key="bill" aws_file="source_files/aws_bill_snapshots.txt" echo "You are currently in account: $aws_account" delete_snapshots break else echo "Unkown account" fi done
关键修改说明
- 函数定义前置:将
delete_snapshots函数移到脚本最顶部,确保Bash在执行调用逻辑前已经加载了函数定义 - 动态Profile参数:把
aws命令中硬编码的--profile=lab改为--profile=$aws_key,让不同账户自动使用对应的AWS配置文件 - 文件路径修正:给快照列表文件加上
source_files/前缀,确保脚本能正确定位到目标文件 - 账户ID修正:修正第一个账户ID的拼写,避免出现匹配错误
内容的提问来源于stack exchange,提问作者bluethundr
相关产品推荐
相关产品推荐

