这个问题有点复杂,首先我要给你介绍一下情况。 我有一个包含许多域的 Web 服务器,我想知道哪些 perl 脚本运行每个域中的用户以及使用哪些参数。
为此我想到重命名 perl,并创建一个名为 perl 的脚本,将环境保存在日志中,然后在 perl 中执行脚本
脚本很简单,但明显有问题
#!/bin/sh
when=`date "+%Y%m%d%H%M%S"`
log_file="/var/logs/perl/${when}"
env > log_file
parameters=$@
echo "Parameters: $parameters" >> $log_file
/usr/local/bin/perl_bin $parameters
我使用一个简单的 perl 脚本来测试:
#!/usr/bin/perl
print "Working\n\n";
问题来了 如果我像这样从 shell 运行 perl 脚本:
perl脚本.pl
工作正常
但是如果我像这样从 shell 运行 perl 脚本:
./script.pl
不起作用,错误看起来是:
./script.pl: 第 3 行:打印:找不到命令
我错过了什么?
最佳答案
如评论中所述,这对您的目的来说可能有点矫枉过正,并且您可能会巧妙地破坏服务器上的每个 Perl 程序(例如,您错误地传递了参数)。你最好使用你的服务器日志或内核级别的东西,比如 lsof
。或者问问自己,为什么您需要知道您的用户正在运行哪些程序。
但是了解正在发生的事情很方便。
#!
中的程序必须是已编译的可执行文件。无法解释。 例如...
$ cat /Users/schwern/tmp/notperl
#!/bin/sh
perl "$@"
$ cat /Users/schwern/tmp/test.pl
#!/Users/schwern/tmp/notperl
print "Hello, world!\n";
$ /Users/schwern/tmp/notperl /Users/schwern/tmp/test.pl
Hello, world!
$ /Users/schwern/tmp/test.pl
/Users/schwern/tmp/test.pl: line 3: print: command not found
发生的事情是 test.pl
被执行并且 program loader看到 shebang line .然后它会检查这是否是可执行程序的绝对路径。不仅仅是任何可执行文件,而是可以由内核直接执行的。
由于 /Users/schwern/tmp/notperl
被解释,内核忽略 #!
行并将其交给 shell 执行。 shell 没有print
函数并告诉您。
通常使用 /usr/bin/env
来解决这个问题。这是一个在修改后的环境中执行另一个程序的小程序。如果没有选项,它只会执行程序。
$ cat /Users/schwern/tmp/test.pl
#!/usr/bin/env /Users/schwern/tmp/notperl
print "Hello, world!\n";
$ /Users/schwern/tmp/test.pl
Hello, world!
在这种情况下,内核使用参数 /Users/schwern/tmp/notperl
执行 /usr/bin/env
。 /usr/bin/env
然后执行 /Users/schwern/tmp/notperl
。
关于linux - 如何使用 shell 脚本拦截 perl 脚本的执行然后实际执行它们?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42704288/