Много утилит, которые работают с файлами, примут stdin (стандартный вход), как передано потоком введено или примут имя файла в качестве параметра.. Ваш < file
примеры перенаправляют вывод файла к утилите. Файл был открыт оболочкой и перешел к Вашей утилите через stdin..
С другой стороны, с cat file
, кошка обрабатывает открытие и чтение файла, и никакое перенаправление не включено.
ls
никогда не читает файл, поэтому он не берет имя файла в качестве параметра в целях открытия и чтения файла.. (это принимает маски имени файла)... Для ls
, действие перенаправления, в действительности, проигнорировано, потому что ничто в процессе не читает открытый для оболочки файл...
Чтобы определить, как любая утилита ведет себя, просто введите man utility-name
в терминале... человек является сокращением руководства..., например. man cat
дарит Вам руководство кошки
Вы не можете.
Сценарий Perl работает в процессе, который является ребенком Вашей сессии оболочки. Этот дочерний процесс может изменить свой собственный рабочий каталог все, что он любит, но он не может измениться, это - рабочий каталог родителя. Когда сценарий Perl выходит, управление возвращается к родительскому процессу (сессия оболочки), который останется в том же рабочем каталоге всем временем, независимо от того, что сделал дочерний процесс, в то время как это работало.
Вы не можете сделать этого непосредственно. Единственный путь к оболочке для изменения ее текущего каталога для самой оболочки для выполнения a cd
команда (или pushd
, popd
, и т.д.).
Но можно сделать это косвенно. Вот простой пример, которые изменяют текущий каталог на /tmp
:
cd-tmp.pl:
#!/usr/bin/perl
print "cd /tmp\n";
В Вашем .bashrc
или .bash_profile
:
cd-tmp() { eval $(cd-tmp.pl); }
Это принимает это cd-tmp.pl
находится в каталоге в Вашем $PATH
- или можно указать полный путь в функции.
Когда Вы вводите cd-tmp
при Вашем приглашении оболочки это вызывает cd-tmp.pl
, получает его вывод и выполняет тот вывод как команду оболочки.
Сценарий Perl не может заставить оболочку вызова изменять каталоги, но он может предоставить ему команду, которую оболочка может затем выполнить сама.
Конечно, можно использовать каталог кроме /tmp
, включая одного это определяется на основе другой информации или создается на лету.
Одна точка разъяснения: текущий каталог является свойством текущего процесса оболочки, не терминала.
ОБНОВЛЕНИЕ:
Я просто понял, что пропустил часть Вашего вопроса; Вы хотите "сценарий жемчуга, который запускает скрипт удара". Достаточно легко изменить мой пример, чтобы сделать это, но я понятия не имею, почему Вам нужен сценарий Perl для запущения скрипта удара. Вы не сказали нам почти достаточно о том, что Вы на самом деле пытаетесь выполнить.
Существует несколько путей (TIMTOWTDI) выполнения внешних команд от Perl. Как использование exec()
, использование обратных галочек ('') и т.д., Если можно выполнить внешние команды прямо из сценария Perl затем, я думаю, нет никакой потребности назвать другой сценарий Bash (но можно сделать это также). Следуйте за ссылкой ниже для узнавания больше. Также отметьте, любые изменения, внесенные в рамках программы, влияет только на подоболочку и остается эффективным всюду по программе только, которая всегда является хорошей вещью, но существуют способы, которыми можно делать изменения постоянными, т.е. она влияла бы на родительскую оболочку также.
http://www.perlhowto.com/executing_external_commands
ОБНОВЛЕНИЕ -
Некоторые вопросы на, "Как сделать это другими способами". Для необычных требований должны быть необычные решения (та работа). Но вопрос состоит в том, почему Вы использовали бы Perl для изменения родительского каталога оболочки? Вот то, как Вы сделали бы это так или иначе
$cat test.pl
print "Hello world\n";
print "cd ..";
$pwd
/home/user/perlcode
$eval `perl test.pl|tee -a test.pl.log|grep cd`
$pwd
/home/user
Можно только сделать это косвенно, например, использующие псевдонимы. Имейте свой сценарий удара, вместо того, чтобы измениться на желаемый каталог, просто распечатайте желаемый каталог к stdout. Perl должен затем получить этот вывод и также распечатать желаемый каталог к stdout. Псевдоним оболочки или функция оболочки могут затем взять тот вывод и изменить каталог в рабочей оболочке.
Пример:
a.sh:
#!/bin/bash
mkdir /tmp/$$
echo /tmp/$$
b.pl:
#!/usr/bin/perl
my $something = do_somestuff();
print `./a.sh $something`;
sub do_somestuff{
#do some processing here
return "";
}
Используйте эту функцию оболочки и протестируйте ее:
daku@server:/home/daku $ b() { DIR=`./b.pl`; if test -n "$DIR"; then cd "$DIR"; fi }
daku@server:/home/daku $ b
daku@server:/tmp/14397 $
b.pl
сценарий был бы проще записан как system './a.sh'
- и это не особенно полезно, так как Вы могли бы также просто вызвать a.sh
непосредственно.
– Keith Thompson
17.07.2012, 21:56
Еще одно решение состоит в том, чтобы сначала сохранить каталог, который Вы хотите посетить в строковой переменной:
Например:
$cd_path = "/var/tmp";
$cmd_to_run = "cd $cd_path ; ls -lrt";
system($cmd_to_run);