#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
write(STDOUT_FILENO, argv[1], atoi(argv[2]));
return 0;
}
以下输出(在Ubuntu上的bash中运行)显示'xyz'未在argv中传递。我想确保这是操作系统的限制,而不是外壳的限制。因此,不可能在argv中的字符串中间传递空字符。有人可以确认吗?谢谢。
$ ./main.exe $'abc\000xyz' 7 | xxd
00000000: 6162 6300 3700 53 abc.7.S
答案 0 :(得分:0)
尽管有OS实现,所有程序都以exec
调用开始,让我们看看POSIX标准对exec
functions的看法。
int execve(const char * path,char * const argv [],char * const envp []);
argv
是传递给程序的参数,envp
是环境变量。
argv和environ数组均由空指针终止。终止argv数组的空指针不在argc中。
参数argv是指向以null终止的字符串的字符指针数组。
因此,很容易得出结论:
argv
NULL
字符串不能传递给argv,它将终止argv
,并丢弃以下所有参数。argv
中的任何字符串不能包含\x0
字符,\x0
将终止当前参数字符串。python -c 'print "\x30\x00\x31"' | xargs --null prog
尝试:
python -c 'print "\x30\x00\x31"' | strace -f xargs --null echo
我们可以找到:
...
...
...
read(0, "0\0001\n", 4096) = 4
...
...
...
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f09f46d9850) = 21232
strace: Process 21232 attached
...
...
...
[pid 21232] execve("/bin/echo", ["echo", "0", "1\n"], 0x7ffe5ccd7638 /* 74 vars */ <unfinished ...>
它表明xargs
可能在调用\x0
时将包含prog
的参数分成两个参数。不是由Shell完成,不是由OS,libc完成,而是xargs