Shell函数文件名展开异常:为何无法按参数创建对应数量文件?
问题分析与解决办法
嘿,你的问题出在Shell的展开顺序上,这是新手写Shell函数时很容易踩的坑!
核心原因:大括号展开早于变量替换
Shell处理命令的时候,展开顺序是固定的:大括号展开(Brace Expansion) 是最早执行的步骤之一,而参数替换(Parameter Expansion)(也就是$变量的替换)是在它之后才进行的。
当你写touch "$1"{1.."$2"}时,Shell会先处理{1.."$2"},这时候$2还没被替换成实际的数字(比如4),它会把"$2"当成一个字符串,所以这个大括号表达式是无效的,自然没法展开成file1 file2 file3 file4这种形式。
另外,你的函数还有一个小语法问题:所有if [[ ... ]]后面的then前面需要加分号或者换行,否则Shell会把then当成一个独立命令,直接报错。
两种解决方法
方法1:用eval强制二次展开(适合简单场景)
eval会让Shell把已经替换后的命令再重新解析一遍,这样大括号展开就能正确识别变量替换后的数字了。不过要注意,eval有安全风险,但你的函数已经对参数做了严格校验(前缀是纯字母,数字是正整数),所以可以放心用。
修正后的函数:
ejercicio_VI() { if [[ $# -ne 2 ]]; then echo "Esta funcion solo acepta dos parametros" return 255 fi if [[ ! $1 =~ ^[a-zA-Z]+$ ]]; then echo "El primer parametro debe ser una string que matchee con esta expresion regular : ^[a-zA-Z]+$" echo "Asi no creamos archivos basura :P " return 255 fi if [[ ! $2 =~ ^[1-9][0-9]*$ ]]; then echo "El segundo parametro debe ser un numero" return 255 fi eval touch "$1"{1.."$2"} }
(顺便修正了你的正则表达式:原来的^[1-9]([1-9])?+$有问题,应该是^[1-9][0-9]*$,这样能匹配1到任意位数的正整数)
方法2:用循环创建文件(更安全直观)
如果不想用eval,用for循环逐个创建文件是更稳妥的方式,完全避免展开顺序的问题:
ejercicio_VI() { if [[ $# -ne 2 ]]; then echo "Esta funcion solo acepta dos parametros" return 255 fi if [[ ! $1 =~ ^[a-zA-Z]+$ ]]; then echo "El primer parametro debe ser una string que matchee con esta expresion regular : ^[a-zA-Z]+$" echo "Asi no creamos archivos basura :P " return 255 fi if [[ ! $2 =~ ^[1-9][0-9]*$ ]]; then echo "El segundo parametro debe ser un numero" return 255 fi for i in $(seq 1 "$2"); do touch "${1}${i}" done }
这样执行ejercicio_VI file 4就会正确生成file1、file2、file3、file4啦!
内容的提问来源于stack exchange,提问作者Matias Barrios
相关产品推荐
相关产品推荐

