Во-первых, мы должны надежно добраться From
заголовок, который может быть сделан со строгим grep регулярным выражением.
% grep --no-filename --ignore-case '^From:' test.eml
From: mgorven@example.com
Затем мы должны считать количество случаев, которые могут быть, покончили uniq -c
(который требует отсортированного списка).
% grep --no-filename --ignore-case '^From:' *.eml | sort | uniq --count
1 From: mgorven@example.com
3 From: mgorven@example.net
Мы можем затем отсортировать вывод по возникновению, для получения максимума, частого наверху.
% grep --no-filename --ignore-case '^From:' *.eml | sort | uniq --count | sort --general-numeric-sort --reverse
3 From: mgorven@example.net
1 From: mgorven@example.com
Это использует _PATH_BSHELL
как execvp()
который на Linux определяется как /bin/sh
в /usr/include/paths.h
. Это должно совпасть с при выполнении с env
или find -exec
например.
Это не должно, конечно, использовать оболочку входа в систему пользователя. То, что Вы видите bash
выше то, потому что это bash
(оболочка, в которую Вы вводите ту командную строку), который пытается выполнить ее и когда это получает a ENOEXEC
код ошибки от execve
это решает интерпретировать его с собой вместо этого (в sh
режим эмуляции).
Ядро может только выполнить двоичные исполняемые изображения. Таким образом, как сценарии становятся выполненными? В конце концов, я могу ввести my_script_without_shebang
при приглашении оболочки и я не добираюсь ENOEXEC
ошибка. Выполнение сценария сделано не ядром, а оболочкой. Исполнительный код в оболочке обычно смотрит что-то как:
/* try to run the program */
execl(program, basename(program), (char *)0);
/* the exec failed -- maybe it is a shell script without shebang? */
if (errno == ENOEXEC)
execl ("/bin/sh", "sh", "-c", program, (char *)0);
Можно проверить что с трассировкой фиктивного сценария оболочки без хижины:
cat > /tmp/foo.sh <<EOF
echo
EOF
chmod u+x /tmp/foo.sh
strace /tmp/foo.sh 2>&1 | grep exec
execve("/tmp/foo.sh", ["/tmp/foo.sh"], [/* 28 vars */]) = -1 ENOEXEC (Exec format error)
Таким образом, выполнение продолжаются как описанный Stephane - оболочка по умолчанию используется (в вышеупомянутом фрагменте кода, трудно кодируется). Этот хороший UNIX FAQ может ответить больше.
Поскольку Вы не используете -s
опция, таким образом, sudo
будет использовать _PATH_BSHELL
(который является, определяют в /usr/include/paths.h
на Ubuntu 12.04 LTS) для установки $SHELL
это работает. Заглядывание к sudo
исходный код:
/* Stash user's shell for use with the -s flag; don't pass to plugin. */
if ((ud->shell = getenv("SHELL")) == NULL || ud->shell[0] == '\0') {
ud->shell = pw->pw_shell[0] ? pw->pw_shell : _PATH_BSHELL;
}
Если Вы используете -s
опция, sudo
будет использовать Ваш $SHELL
вместо _PATH_BSHELL
:
$ cat ./test.sh
ps | grep "$$" | awk '{ print $4 }'
$ ./test.sh
bash
$ sudo -s ./test.sh
bash
-s
не означает, что сценарий будет интерпретироваться $SHELL
, это просто означает, что (принятие Вы были разрешены использовать $SHELL
как целевой пользователь), команда запускается как $SHELL -c ./test.sh
. Оболочки как bash
, yash
или ksh93
может принять решение интерпретировать she-bang-less сценарии с копией себя, другие не были бы и называть систему sh
вместо этого.
– Stéphane Chazelas
27.09.2013, 14:05
exec($SHELL, "-c", "./test.sh")
безусловно вместо if (exec("./test.sh") == ENOEXEC) exec(_PATH_BSHELL, "./test.sh")
(псевдокод).
– Stéphane Chazelas
27.09.2013, 15:21
sh
или синтаксический анализ/etc/passwd
когда это receievesENOEXEC
ошибка? – layka 27.09.2013, 17:11sudo
не будет использовать оболочку входа в систему пользователя, если Вы не говорите ей путем сообщения ей, который Вы хотите передать ее командная строка для интерпретации оболочкой (с-s) в противоположность команде для выполнения. Если команда для выполнения это будет вести себя какexecvp
, это похоже на систему, предназначен для выполнения команд. – Stéphane Chazelas 27.09.2013, 17:19sudo
всегда устанавливайте его среду выполнения, предшествующую вызов кexecve()
. Если Вы не передаете-s
, sudo будет использовать_PATH_BSHELL
. – cuonglm 27.09.2013, 17:31execvp()
. Это может также использовать _PATH_BSHELL с-s при выполнении$SHELL
возвраты ENOEXEC. См. мой комментарий к своему ответу для получения дополнительной информации. – Stéphane Chazelas 27.09.2013, 20:43