Can I execute a multiline command in Perl's backticks? - perl

In Unix, I have a process that I want to run using nohup. However this process will at some point wait at a prompt where I have to enter yes or no for it to continue. So far, in Unix I have been doing the following
nohup myprocess <<EOF
y
EOF
So I start the process 'myprocess' using nohup and pipe in a file with 'y' then close the file. The lines above are effectively three seperate commands - i.e. I hit enter on the first line in UNIX, then I get a prompt where I enter 'y' and then press enter to then finally type 'EOF' and hit return again.
I want to know execute this in Perl but I am not sure how I can execute this command as it is over three lines. I don't know if the following will work....
my $startprocess = `nohup myprocess <<EOF &
y
EOF
`
Please help - thank you!

I think your proposal will work as is. If not, try replacing the redirect with a pipe:
my $startprocess = `(echo "y" | nohup myprocess) &`;
Also, depending on WHY you are doing a nohup, please look at the following pure Perl daemonizing approach using Proc::Daemon : How can I run a Perl script as a system daemon in linux?

Expect for interactive programs can be used as well.

Related

unable to take user input in perl

I am having a strange issue. I have written a script which is basically running a perl script in remote server using ssh.
This script is working fine but after completion of the above operation it will ask user to choose the next operation.
it is showing the options in the command prompt but while I am giving any input it is not showing in the screen even after hitting enter also it remain same.
I am not getting what is the exact issue, but it seems there is some issue with the ssh command because if I am commenting out the ssh command it is working fine.
OPERATION:
print "1: run the script in remote server \n2: Exit\n\nEnter your choice:";
my $input=<STDIN>;
chomp($input);
..........
sub run_script()
{
my $com="sshg3.exe server -q --user=user --password=pass -exec script >/dev/null";
system("$com");
goto OPERATION;
}
after completing this ssh script it is showing in screen:
1: run remote script
2: exit
Enter your choice:
but while I am giving any input it is not displaying in the screen until and unless I am exiting it using crtl C.
Please can anyone help what might be the issue here ?
One of the classic gotchas with ssh is this - that it normally runs interactively, and as such will attach STDIN by default.
This can result in STDIN being consumed by ssh rather than your script.
Try it with ssh -n instead.
You can redirect the output in command prompt if -n option is not available for you.
try this one it might work for you.
system("$com />null");
As per https://support.ssh.com/manuals/client-user/62/sshg3.html there is an option for redirecting input use --dev-null (*nix) or --null (Windows).
-n, --dev-null (Unix), -n, --null (Windows)
Redirects input from /dev/null (Unix) and from NUL (Windows).

Terminal prompt disappears when a named pipe is used

I'm trying to use named pipes in a project. I have two terminals open, Terminal A and Terminal B.
In terminal A, I issued this command:
mkfifo myFifo && tail -f myFifo | csh -s
It seems as if standard out is being redirected somewhere else, though, because my prompt disappears and some commands aren't reflected in terminal A.
For example, if in terminal B I begin a python session via issuing echo "python" > myFifo, then echo "print 'Hello, World'" > myFifo, I don't see Hello, World in terminal A.
However, if I issue echo ls > myFifo within terminal B, I see the correct output from ls in terminal A.
Does anyone know why sometimes the output appears and sometime it doesn't?
I'm running on CentOS 6.6
Thanks,
erip
You read from the FIFO with csh, if you start an interactive Python shell in csh, then it won't be reading from the FIFO because it's busy running python.
Python doesn't somehow automagically do a REPL on the FIFO. How should it even know about the FIFO? It has no knowledge of it.
You could, perhaps, tell Python to read commands from the FIFO with something like:
>>> import os, sys, time
>>> fifo = open(os.open('myFifo', os.O_NONBLOCK), 'r')
And then:
$ echo 'print(42+5)' > ! myFifo
Will give you:
>>> eval(fifo.read())
47
Perhaps there's also a way to tell Python to read commands from myFifo by overwriting sys.stdin, but I can't get that working in my testing.
It's a bit unclear to me what exactly you're trying to achieve here, though. I suspect there might be another solution which is much more appropriate to the problem you're having.

Waitfor doesn't recognize the expression in Perl

I've a waitfor command, but its not recognizing the pattern. What may be wrong?
while(#wait = $t->waitfor('/bash-3.2\$ $/i'))
Thanks,
Sharath
You need to set the waitfor to match your PS1 prompt.
On my machine if I:
export PS1=export PS1="\s-\v\$"
my prompt becomes:
bash-3.2$
So I think your code should be looking for
while(#wait = $t->waitfor('/bash\-3\.2\$/i'))
Which hopefully matches
I have to wonder though if your regex is the problem.
If you run an interactive command such as bash it will never return control to the program as it has no user input. Also, the while loop scares me a bit. I'm not sure why you need that.
If you really need bash try running your commands with bash -c <some command>
That way bash will run your single command and return the result.

How to run a applescript to enter a terminal command

I have been messing around with voice commands, but ran into a snag. I am trying to get a terminal command to run but it is not working. The command makes asterisks "snow" fall.
This is what I have so far.
tell application "Terminal"
activate
run script "ruby -e 'C=`stty size`.scan(/\d+/)[1].to_i;S=["2743".to_i(16)].pack("U*");a={};puts "\033[2J";loop{a[rand(C)]=0;a.each{|x,o|;a[x]+=1;print "\033[#{o};#{x}H \033[#{a[x]};#{x}H#{S} \033[0;0H"};$stdout.flush;sleep 0.1}'"
end tell
All I get are errors
Command line scripts executed with the do shell script command. The string escaping can get a bit gnarly, so be careful with that too. Here's a simple example:
do shell script "say \"Today is `php -r \"echo date('l');\"`\""
EDIT:
OK, I just realised your script actually depends on having a Terminal window to run in, so the usual approach of do shell script won't work here.
There are still a lot of unescaped quotation marks in your Applescript, but rather than fixing those, I think it would be easier to put the whole ruby script into a stand-alone file and pass that to Terminal instead.
stars.rb
#!/usr/bin/ruby
C=`stty size`.scan(/\d+/)[1].to_i;
S=["2743".to_i(16)].pack("U*");
a={};
puts "\033[2J";
loop {
a[rand(C)]=0;
a.each {
|x,o|;
a[x]+=1;
print "\033[#{o};#{x}H \033[#{a[x]};#{x}H#{S} \033[0;0H"
};
$stdout.flush;
sleep 0.1
}
AppleScript
tell application "Terminal"
activate
do script "~/stars.rb"
end tell
An easy way to escape a shell command for AppleScript is to save the command in a text file. Run the script below and copy the Result.
set myText to read (choose file) as «class utf8»

Why is this command not running in background which is enclosed with Backticks ( PERL )

I am running script with arguments inside the perl script. script and arguments are enclosed with backticks. When I use '&' symbol at last after arguments, the command is not running on background, it is running on foreground. can someone find the mistake in my program. I need to save the output and redirect the same to one variable and then to log.
Below is the code of mine:
open (MYSM, "> /logs/${SM}.smlog");
open (MYSP, "> /logs/${SM}.splog");
$SM_LOG_VAR = ` ./sm.sh $SE_VER $SMS_VERSION & ` ;
$SP_LOG_VAR = ` ./sp.sh $SE_VER $SMS_VERSION ` ;
print MYSM $SM_LOG_VAR ;
print MYSP $SP_LOG_VAR ;
close(MYSM);
close(MYSP);
The line :
$SM_LOG_VAR = ` ./sm.sh $SE_VER $SMS_VERSION & ` ;
is not running in background which is completely enclosed with backticks.
The backticks themselves will complete only when the command completes. You want something like fork + exec or perhaps dup2. Anyway, how would the program proceed with a value for $SM_LOG_VAR if the command to obtain that information has not yet finished?
I think your asking the wrong question, from reading your code let me guess at your real problem. You have a Perl script that does some work not shown to set some variables that are then used to run 2 external programs. You want to run both programs simultaneously and store the output from each to it's own log file.
The simplest way to accomplish this is to run both programs in the background and have the shell do the redirection.
system("./sm.sh $SE_VER $SMS_VERSION > /logs/${SM}.smlog &");
system("./sp.sh $SE_VER $SMS_VERSION > /logs/${SM}.splog &");
This will return to your script without waiting for either program to finish, if you have code later in the program that requires that the commands be completed then you will may need a more complex solution.
I would look at:
Perl Backticks
If you want to run it in the background I would try something like open3:
IPC::Open3