csh中如何从STDOUT读取内容实现source?求替代eval与临时文件的方案
在csh中替代
source <()的方案(无需临时文件) 针对你需要同时兼容bash和csh设置环境变量的场景,csh本身不支持bash的进程替换语法<(),除了临时文件,这里提供两种可行的替代方案:
1. 优化eval的命令长度问题
如果你担心eval \init_script args``的命令行过长,可以从调整init_script的输出格式入手:
- 让init_script先检测当前运行的shell类型(通过
BASH_VERSION或CSH_VERSION环境变量),然后输出紧凑的变量设置命令:- 对bash:用
export VAR1=val1 VAR2=val2 ...一次性导出多个变量,减少命令数量 - 对csh:把多个
setenv命令用分号分隔,合并成单条或少数几条命令
这种方式能大幅降低单条命令的长度,规避csh的命令行长度限制。
- 对bash:用
示例init_script片段:
#!/bin/sh if [ -n "$BASH_VERSION" ]; then export PATH="/new/path:$PATH" LD_LIBRARY_PATH="/new/lib:$LD_LIBRARY_PATH" elif [ -n "$CSH_VERSION" ]; then setenv PATH "/new/path:$PATH"; setenv LD_LIBRARY_PATH "/new/lib:$LD_LIBRARY_PATH" fi
2. 使用命名管道(FIFO)模拟进程替换
命名管道是内存级的临时通道,不会在磁盘留下永久文件,且能让csh的source直接读取init_script的输出:
# 创建临时命名管道,用进程ID避免冲突 mkfifo /tmp/$$.pipe # 后台运行init_script,将输出写入管道 init_script args > /tmp/$$.pipe & # 从管道读取内容并source source /tmp/$$.pipe # 清理管道 rm /tmp/$$.pipe
这个方案完全规避了命令行长度问题,效果和bash的source <()几乎一致,且比临时文件更干净。
内容的提问来源于stack exchange,提问作者kdubs
相关产品推荐
相关产品推荐

