【发布时间】:2011-05-19 06:50:25
【问题描述】:
我有一个脚本,用于在调用 csh shell 中设置一些环境变量。其中一些变量取决于脚本的位置。
如果文件是正确的 csh 脚本,我可以使用 $0 访问 __FILE__,但如果我使用源代码运行脚本,它只会告诉我 csh 或 tcsh。
由于我使用它在父 shell 中设置变量,所以我必须使用 source.
怎么办?
【问题讨论】:
我有一个脚本,用于在调用 csh shell 中设置一些环境变量。其中一些变量取决于脚本的位置。
如果文件是正确的 csh 脚本,我可以使用 $0 访问 __FILE__,但如果我使用源代码运行脚本,它只会告诉我 csh 或 tcsh。
由于我使用它在父 shell 中设置变量,所以我必须使用 source.
怎么办?
【问题讨论】:
如果您在文件的第一行访问$_,它将包含文件的名称(如果它是来源的)。如果直接运行,则$0 将包含名称。
#!/bin/tcsh
set called=($_)
if ($called[2] != "") echo "Sourced: $called[2]"
if ($0 != "tcsh") echo "Called: $0"
【讨论】:
echo HELLO; source test.cshHELLOSourced: HELLO;Called: /bin/tcsh`
$_ 真的“替换了执行的最后一个命令的命令行。”
这很难阅读,但确实有效:
如果你的脚本名为 test.csh
/usr/sbin/lsof +p $$ | \grep -oE /.\*test.csh
【讨论】:
/usr/sbin/lsof -p $$ | grep -oE /.\*test.csh。 linux.die.net/man/8/lsof
this answer 描述了 lsof 和一点 grep 魔法是唯一似乎有机会处理 csh/tcsh 下的嵌套源文件的方法。
如果你的脚本被命名为source_me.tcsh:
/usr/sbin/lsof -p $$ | grep -oE '/.*source_me\.tcsh'
【讨论】:
$$ 在子 shell 中调用源代码时不起作用。 BASH_PID 仅适用于 bash。
% (sleep 1; source source_me.csh)
我发现以下工作更好一些:
% set pid=`cut -d' ' -f4 < /proc/self/stat`
% set file=`/usr/sbin/lsof +p $pid|grep -m1 -P '\s\d+r\s+REG\s' | xargs | cut -d' ' -f9`
第一行查找获取文件的当前进程的 pid。这来自Why is $$ returning the same id as the parent process?。第二行查找为读取常规文件而打开的第一个(希望是唯一的)FD。这来自上面的 engtech。
【讨论】: