Сценарий Perl, сделайте CD на терминале

Много утилит, которые работают с файлами, примут stdin (стандартный вход), как передано потоком введено или примут имя файла в качестве параметра.. Ваш < file примеры перенаправляют вывод файла к утилите. Файл был открыт оболочкой и перешел к Вашей утилите через stdin..

С другой стороны, с cat file, кошка обрабатывает открытие и чтение файла, и никакое перенаправление не включено.

ls никогда не читает файл, поэтому он не берет имя файла в качестве параметра в целях открытия и чтения файла.. (это принимает маски имени файла)... Для ls, действие перенаправления, в действительности, проигнорировано, потому что ничто в процессе не читает открытый для оболочки файл...

Чтобы определить, как любая утилита ведет себя, просто введите man utility-name в терминале... человек является сокращением руководства..., например. man cat дарит Вам руководство кошки

3
13.04.2017, 15:36
5 ответов

Вы не можете.

Сценарий Perl работает в процессе, который является ребенком Вашей сессии оболочки. Этот дочерний процесс может изменить свой собственный рабочий каталог все, что он любит, но он не может измениться, это - рабочий каталог родителя. Когда сценарий Perl выходит, управление возвращается к родительскому процессу (сессия оболочки), который останется в том же рабочем каталоге всем временем, независимо от того, что сделал дочерний процесс, в то время как это работало.

9
27.01.2020, 21:08

Вы не можете сделать этого непосредственно. Единственный путь к оболочке для изменения ее текущего каталога для самой оболочки для выполнения 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 для запущения скрипта удара. Вы не сказали нам почти достаточно о том, что Вы на самом деле пытаетесь выполнить.

4
27.01.2020, 21:08

Существует несколько путей (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
0
27.01.2020, 21:08
  • 1
    И что те пути состоят в том, чтобы влиять на родительскую оболочку? –  Hermann Ingjaldsson 17.07.2012, 17:01

Можно только сделать это косвенно, например, использующие псевдонимы. Имейте свой сценарий удара, вместо того, чтобы измениться на желаемый каталог, просто распечатайте желаемый каталог к 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 $
0
27.01.2020, 21:08
  • 1
    Ваш b.pl сценарий был бы проще записан как system './a.sh' - и это не особенно полезно, так как Вы могли бы также просто вызвать a.sh непосредственно. –  Keith Thompson 17.07.2012, 21:56
  • 2
    Ну, это было только для демонстрации. OP хотел иметь сценарий Perl, который выполняет сценарий оболочки, который изменяет текущий каталог оболочки, запускающей скрипт жемчуга. –  daniel kullmann 17.07.2012, 22:26
  • 3
    , я отсутствовал, "который выполняет сценарий оболочки" часть. Который оставляет нерешенный вопрос: Почему?? –  Keith Thompson 17.07.2012, 22:49

Еще одно решение состоит в том, чтобы сначала сохранить каталог, который Вы хотите посетить в строковой переменной:
Например:

$cd_path = "/var/tmp";
$cmd_to_run = "cd $cd_path ; ls -lrt";
system($cmd_to_run);
0
27.01.2020, 21:08

Теги

Похожие вопросы