【问题标题】:How do I get `__FILE__` when sourcing a csh script采购 csh 脚本时如何获得`__FILE__`
【发布时间】:2011-05-19 06:50:25
【问题描述】:

我有一个脚本,用于在调用 csh shell 中设置一些环境变量。其中一些变量取决于脚本的位置。

如果文件是正确的 csh 脚本,我可以使用 $0 访问 __FILE__,但如果我使用源代码运行脚本,它只会告诉我 csh 或 tcsh。

由于我使用它在父 shell 中设置变量,所以我必须使用 source.

怎么办?

【问题讨论】:

标签: csh tcsh


【解决方案1】:

如果您在文件的第一行访问$_,它将包含文件的名称(如果它是来源的)。如果直接运行,则$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`
  • @engtech:那是因为$_ 真的“替换了执行的最后一个命令的命令行。”
【解决方案2】:

这很难阅读,但确实有效:

如果你的脚本名为 test.csh

/usr/sbin/lsof +p $$ | \grep -oE /.\*test.csh

【讨论】:

  • 我比接受的答案更喜欢这个。如果您可以严格控制脚本的来源,则使用 $_ 有效。
  • lsof 选项+p 有什么作用?我认为选项应该是-p来选择父shell的进程号,所以/usr/sbin/lsof -p $$ | grep -oE /.\*test.cshlinux.die.net/man/8/lsof
【解决方案3】:

this answer 描述了 lsof 和一点 grep 魔法是唯一似乎有机会处理 csh/tcsh 下的嵌套源文件的方法。

如果你的脚本被命名为source_me.tcsh:

/usr/sbin/lsof -p $$ | grep -oE '/.*source_me\.tcsh'

【讨论】:

    【解决方案4】:

    $$ 在子 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。

    【讨论】:

      猜你喜欢
      • 2022-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-10
      • 1970-01-01
      • 2010-11-29
      相关资源
      最近更新 更多