Fish Shell中rmccw函数执行异常:编译器报错求助
解决Fish Shell中
rmccw *执行时编译器报错的问题 问题根源
Fish Shell的通配符展开时机是核心问题:当执行rmccw *时,Fish会在调用rmccw函数之前就把*展开为当前目录下的所有文件(包括存在的a.out),并将这些文件名作为参数传递给函数。
虽然rmouts确实删除了a.out,但ccw已经拿到了a.out这个参数,gcc尝试将其作为输入文件,同时默认输出到a.out,直接触发"输入文件与输出文件相同"的报错。
而直接执行rmouts && ccw *时,rmouts执行完成后ccw *才展开通配符,此时a.out已不存在,参数中没有它,因此编译正常。
解决方法
方法1:函数内部自行处理通配符与过滤
修改rmccw函数,在内部主动获取当前目录下非.out结尾的文件,避免依赖外部提前展开的通配符:
function rmccw rmouts # 获取当前目录下所有非.out文件,传给ccw ccw (string match -v '*.out' *) end
这种方式最直接,不管用户输入的是rmccw *还是具体文件名,函数都会自动过滤掉.out文件,确保gcc不会拿到已删除的输出文件作为输入。
方法2:过滤传入的参数(兼容任意输入场景)
如果需要兼容用户传入具体文件名的场景,可以先过滤函数收到的参数,去掉.out结尾的文件:
function rmccw rmouts # 过滤掉参数中所有.out结尾的文件 set filtered_args (string match -v '*.out' $argv) ccw $filtered_args end
这种方式既处理了rmccw *的场景,也支持用户传入单个或多个指定文件名的情况。
方法3:强制指定编译器输出文件名(可选)
如果希望彻底避免输入输出文件名冲突,可以修改ccw函数,固定输出文件名:
function ccw cc $argv -Wall -Wextra -Werror -o main.out end
这样即使参数中意外包含输出文件,也不会触发冲突,但这属于规避问题,而非从根源解决通配符展开的问题。
内容的提问来源于stack exchange,提问作者Bruno Moretti
相关产品推荐
相关产品推荐

