不要求第一的論點承擔任何有關的可執行文件的名稱:
int main(void)
{
char *args[3] = { "rip van winkle", "30", 0 };
execv("/bin/sleep", args);
return 1;
}
試試吧 - 在Mac上(後三項測試):
make x; ./x & sleep 1; ps
在第三運行的輸出是:
MiniMac JL: make x; ./x & sleep 1; ps
make: `x' is up to date.
[3] 5557
PID TTY TIME CMD
5532 ttys000 0:00.04 -bash
5549 ttys000 0:00.00 rip van winkle 30
5553 ttys000 0:00.00 rip van winkle 30
5557 ttys000 0:00.00 rip van winkle 30
MiniMac JL:
EBM評論:
呀,這使它更加怪異。在我的測試bash腳本(execve的目標)中,我沒有看到execve在arg [0]中的任何地方的價值 - 而不是在環境中,而不是$ 0。
修改實驗 - 一個名爲'bash的腳本。腳本':
#!/bin/bash
echo "bash script at sleep (0: $0; *: $*)"
sleep 30
而修訂的計劃:
int main(void)
{
char *args[3] = { "rip van winkle", "30", 0 };
execv("./bash.script", args);
return 1;
}
這就產生ps輸出:
bash script at sleep (0: ./bash.script; *: 30)
PID TTY TIME CMD
7804 ttys000 0:00.11 -bash
7829 ttys000 0:00.00 /bin/bash ./bash.script 30
7832 ttys000 0:00.00 sleep 30
有兩種可能性,因爲我看到它:
- 內核在通過腳本執行腳本時會對命令行進行操作shebang('
#!/bin/bash
')行,或
- Bash本身與其參數列表沾在一起。
如何建立區別?我想複製殼的替代名稱,然後使用在家當替代名稱會告訴我們一些東西:
$ cp /bin/bash jiminy.cricket
$ sed "s%/bin/bash%$PWD/jiminy.cricket%" bash.script > tmp
$ mv tmp bash.script
$ chmod +w bash.script
$ ./x & sleep 1; ps
[1] 7851
bash script at sleep (0: ./bash.script; *: 30)
PID TTY TIME CMD
7804 ttys000 0:00.12 -bash
7851 ttys000 0:00.01 /Users/jleffler/tmp/soq/jiminy.cricket ./bash.script 30
7854 ttys000 0:00.00 sleep 30
$
此,我認爲,表示所使用的家當機制,當內核重寫argv[0]
。
解決因nategoose評論:「#!/路徑/到/程序」
MiniMac JL: pwd
/Users/jleffler/tmp/soq
MiniMac JL: cat al.c
#include <stdio.h>
int main(int argc, char **argv)
{
while (*argv)
puts(*argv++);
return 0;
}
MiniMac JL: make al.c
cc al.c -o al
MiniMac JL: ./al a b 'c d' e
./al
a
b
c d
e
MiniMac JL: cat bash.script
#!/Users/jleffler/tmp/soq/al
echo "bash script at sleep (0: $0; *: $*)"
sleep 30
MiniMac JL: ./x
/Users/jleffler/tmp/soq/al
./bash.script
30
MiniMac JL:
這表明它是家當機制,而不是任何程序,如猛砸,即調整argv[0]
的值。所以,執行二進制時,argv[0]
的值不會被調整;當通過shebang執行腳本時,參數列表由內核調整; argv[0]
是shebang上列出的二進制文件;如果在shebang之後有爭論,那就變成argv[1]
;下一個參數是腳本文件的名稱,後跟execv()
或同等調用的其餘參數。
MiniMac JL: cat bash.script
#!/Users/jleffler/tmp/soq/al -arg0
#!/bin/bash
#!/Users/jleffler/tmp/soq/jiminy.cricket
echo "bash script at sleep (0: $0; *: $*)"
sleep 30
MiniMac JL: ./x
/Users/jleffler/tmp/soq/al
-arg0
./bash.script
30
MiniMac JL:
您需要雙引號;並可能是一個空char *來終止參數列表,假設您使用的是execl()。 – 2010-06-12 03:28:26
我會接受你的話,但有趣的是,我創建了一個測試,執行一個簡單的bash腳本,吐出$ 0,甚至當我使用「美化」程序名時,$ 0仍然是完整路徑execve()的第一個參數,那麼,我假設)。 – EBM 2010-06-12 03:30:32
@Johnathan:怪罪Python。 – 2010-06-12 03:31:19