[nix] Зачем "./" в пути к скрипту?

taira1983

Есть перловый скрипт.
Что значит его запуск вот в таком виде:
 ./Postmaster.pl

pitrik2

это значит
1) этот вопрос надо задавать в разделе альт.юникс или в разделе харднсофт
2) атрибуты на файл стоят +x, т.е. на запуск
3) в начале файла написана команда которой этот файл выполняется
обычно это
#!/usr/bin/perl
4) если выполнено 2 и 3 то выполнится команда из пункта 3 и ей подставится оставшийся файл

taira1983

это значит1) этот вопрос надо задавать в разделе альт.юникс или в разделе харднсофт2) атрибуты на файл стоят +x, т.е. на запуск3) в начале файла написана команда которой этот файл выполняетсяобычно это#!/usr/bin/perl4) если выполнено 2 и 3 то выполнится команда из пункта 3 и ей подставится оставшийся файл
условия 2 и3 соблюдены
Как я понял бонус в том, что скрип сам указывает на то , чем его выполнять.
 Нашел в поисковике по ключевому слову dot-slash

Elina74

ты переходишь в папку, где этот файл лежит, пишешь то самое.
./ означает запуск файла из текущей директории

Elina74

Postmaster.pl
если ты находишься в той директории, где лежит этот файл, но текущая директория не находится в переменной $path, то ОС не сможет понять, что и откуда запускать, если ты напишешь просто Postmaster.pl

taira1983

Всем большой спасибо.

kruzer25

3) в начале файла написана команда которой этот файл выполняется
А если бинарник?
cd /bin
./ls

pitrik2

вопрос был про перл скрипты
причем тут бинарник?
ты не в теме

tipnote

Нашел в поисковике по ключевому слову dot-slash
пункт три ищется по shebang Хрен сам догадаешься

tokuchu

А если бинарник?
cd /bin
./ls
Один хер. У бинарников заголовок начинается с других символов, а не с "#!".
Процедура запуска для всех одинаковая.

taira1983

Вся эта морока c "./" из-за того, что в переменной PATH не указана "."
Т.е. bash или sh тупо не найдут скрипт в той директории откуда запускаешь, т.к. ищут только по путям из PATH.
Возникает уже философский вопрос: из каких соображений текущая директория не входит в список поиска ?

artimon

Из соображений безопасности.
Представь, что «.» добавлена в PATH.
Я иду в каталог /tmp и создаю там файлик ls, который делает что-то нехорошее.
Потом в этот каталог заходишь ты и набираешь ls и твой аккаунт уже похачен

apl13

Post deleted by

Ober

команда "echo $PATH | grep './'" выдает пустую строку...
В такой постановке — вряд ли =]

apl13

Post deleted by

Ober

предположения?
Очень сурово, наверное, жить с $PATH, для которого "echo $PATH | grep './'" выдаёт пустую строку =] Но, действительно, не лишено смысла!
% echo '/bin' | grep './'
% echo '/bin:/usr/bin' | grep './'
/bin:/usr/bin

apl13

Post deleted by

Ober

grep '\./'
Ура! Почти торжество справедливости и Нового Мирового Порядка.
% echo '.:/bin:/usr/bin' | grep '\./'
%

P.S. '\./' — это из онеме что ли смайлик?

apl13

Милиция-а-а...

zya369


---:~> ll 1
-rwxr-xr-x 1 kurgedu users 11 2007-08-14 12:40 1
---:~> cat 1
echo "123"
---:~> ./1
123
---:~>

никаких заголовков, а все пашет

Ober

Милиция не поможет. Зови скорей военную прокуратуру!

pitrik2

никаких заголовков, а все пашет
сомневаюсь
пашет в bash
а в другой командной оболочке будет пахать?

zya369

в AIX'е с ksh пашет

tokuchu

никаких заголовков, а все пашет
Это потому, что ты из шелла запускаешь. А он если не может запустить программу, то считает, что это скрипт и пробует сам обработать. Но такую программу может не получиться запустить из другой программы, например с помощью вызова exec(3) - вернётся ошибка.

pitrik2

а если будет #!/команда
то exec(3) прокатит?

tokuchu

а если будет #!/команда
то exec(3) прокатит?
да, причём достаточно префикса "#!". Тогда весь файл будет интерпретироваться таким образом. Т.е. дальше вытаскивается команда, которой надо скормить данный файл и т.д.
Ну т.е. может быть "#! /bin/sh" (с пробелом).

kruzer25

вопрос был про перл скрипты
Вопрос был про запуск вообще.
Хотя да, в примере был файл, кончающийся на .pl (что ничего не означает)

Ivan8209

"Запуск вообще" описан в execve(2).
---
"This user is BSD-compliant."

Ivan8209

Если просто "команда" --- нет.
man 3 exec.
---
"This user is BSD-compliant."

Ivan8209

Вот это одинаково запускается что из /bin/sh, что из
/usr/pkg/bin/gforth с помощью FFI (ffcall) и execvp(3):

$ bat-state
acpibat0 charge: 7.800 Ah (121.99%)
acpibat0 warn cap: 0.780 Ah (12.20%)
acpibat0 low cap: 0.236 Ah ( 3.69%)
$ cat `which bat-state`
/usr/sbin/envstat -d acpibat0 -s 'acpibat0 charge'
/usr/sbin/envstat -d acpibat0 -s 'acpibat0 warn cap'
/usr/sbin/envstat -d acpibat0 -s 'acpibat0 low cap'
$ stat -f "%Sp" `which bat-state`
-rwxr-xr-x

Навряд ли во FreeBSD отказались от этого,
FreeBSD не менее консервативная система.
По крайней мере, в начале лета такое работало.
---
"Три кольца отдали бессмертным эльфам.
Чисто для проверки: не передохнут ли?"

tokuchu

Вот это одинаково запускается что из /bin/sh, что из
/usr/pkg/bin/gforth с помощью FFI (ffcall) и execvp(3):
Хз чего там gforth делает, может он её через sh сам вызывает.
Я проверял в Linux:

$ cat ex.c
#include <unistd.h>
int main(int argc, char **argv)
{
++argv;
execv(*argv, argv);
return 1;
}
$ gcc -o ex ex.c
$ ls -l 1.sh 2.sh
-rwxr-xr-x 1 user user 8 Авг 16 12:27 1.sh
-rwxr-xr-x 1 user user 18 Авг 16 12:30 2.sh
$ cat 1.sh
echo ok
$ cat 2.sh
#!/bin/sh
echo ok
$ ./ex ./1.sh || echo fail
fail
$ ./ex ./2.sh || echo fail
ok

Сейчас проверил под FreeBSD. Результат тот же.

Ivan8209

> Очень сурово, наверное, жить с $PATH, для которого
> "echo $PATH | grep './'" выдаёт пустую строку =]
Символические ссылки решают:
export PATH=/run
---
"Расширь своё сознание!"
P.S. cat /usr/pkgsrc/sysutils/depot/DESCR

Ivan8209

> Хз чего там gforth делает, может он её через sh сам вызывает.
Читать не умеешь?
Вызов делается из execvp, напрямую, если не считать FFI,
где расположена эта execvp, прочитаешь в /usr/src/lib,
ибо во фре она может быть расположена где-то не там.

$ cat run.c
#include <unistd.h>
int
main(int argc, char *argv[])
{
argv++;
execvp(*argv, argv);
return 1;
}
$ make run
cc -O2 -o run run.c
$ ./run bat-state
acpibat0 charge: 7.800 Ah (121.99%)
acpibat0 warn cap: 0.780 Ah (12.20%)
acpibat0 low cap: 0.236 Ah ( 3.69%)
$ ./run `which bat-state`
acpibat0 charge: 7.800 Ah (121.99%)
acpibat0 warn cap: 0.780 Ah (12.20%)
acpibat0 low cap: 0.236 Ah ( 3.69%)
$ cat `which bat-state`
/usr/sbin/envstat -d acpibat0 -s 'acpibat0 charge'
/usr/sbin/envstat -d acpibat0 -s 'acpibat0 warn cap'
/usr/sbin/envstat -d acpibat0 -s 'acpibat0 low cap'
$ stat -f "%Sp" `which bat-state`
-rwxr-xr-x

---
"NetBSD is JIHBED!"

Ober

Вот и я говорю о том, что суровые люди боевым криком разрывают мелких домашних животных на куски :]

tokuchu

Читать не умеешь?
Вызов делается из execvp, напрямую, если не считать FFI,
Бля, протупил чего-то.
где расположена эта execvp, прочитаешь в /usr/src/lib,
Какая разница где она расположена?
В общем, NetBSD (я правильно понял?) ведёт себя как-то по-другому чем Linux и FreeBSD.
Возможно оно по умолчанию, если не определяет формат файла, то кормит его /bin/sh.

Ivan8209

> В общем, NetBSD (я правильно понял?) ведёт себя как-то
> по-другому чем Linux и FreeBSD.
Э-э-э, "top and power intelligent?"

/* $NetBSD: execvp.c,v 1.30 2007/07/20 12:41:07 yamt Exp $ */

...

retry: (void)execve(bp, argv, environ);
switch (errno) {

...

case ENOEXEC:
for (cnt = 0; argv[cnt] != NULL; ++cnt)
continue;
/*
* we can't use malloc here because, if we are doing
* vfork+exec, it leaks memory in the parent.
*/
if memp = allocacnt + 2) * sizeof(*memp == NULL)
goto done;
memp[0] = _PATH_BSHELL;
memp[1] = bp;
(void)memcpy(&memp[2], &argv[1], cnt * sizeof(*memp;
(void)execve(_PATH_BSHELL, __UNCONST(memp environ);
goto done;


EXECVE(2) NetBSD System Calls Manual EXECVE(2)

NAME
execve -- execute a file

...

ERRORS
execve will fail and return to the calling process if:

...

[ENOEXEC] The new process file has the appropriate access per-
mission, but has an invalid magic number in its
header.

Вообще-то, это поведение (вызов /bin/sh для неопределяющегося
по "magic" файла) идёт из глубины веков, оно было завещано
отцами-основателями и изменению не подлежит:

In the cases where the other members of the exec family of
functions would fail and set errno to [ENOEXEC], the execlp
and execvp functions shall execute a command interpreter and
the environment of the executed command shall be as if the
process invoked the sh utility using execl as follows:

execl(<shell path>, arg0, file, arg1, ..., (char *)0);


SUSv3; IEEE Std 1003.1, 2004.
Вывод: FreeBSD и Linux не следуют POSIX.
---
"Три кольца отдали бессмертным эльфам.
Чисто для проверки: не передохнут ли."

Ivan8209

Бли-и-ин!
> execv(*argv, argv);
Ну ёклмн!
---
"То, что у Вас пока нет судимости, не Ваша заслуга, а наша недоработка."

tokuchu

Бли-и-ин!
> execv(*argv, argv);
Ну ёклмн!
Ага.
Читать умеешь?

execvp у меня тоже сам sh вызывает. Значит мы говорили о разном.

Ivan8209

Не, я понимаю, что с точки зрения безопасности лучше вызывать
без обращения к PATH и shell, но не с точки зрения удобства.
Тогда полезный ответ на исходный вопрос ("exec прокатит?") такой:
Нет такой функции в libc!
---
"Всю цепь силлогизмов не читал."
Оставить комментарий
Имя или ник:
Комментарий: