Executing external programs in Perl - linux

I am executing a few external programs from a Perl script and want to automatically handle prompts from that program. I know what the prompts are, they are not error conditions, and I want the script to handle them and not the user.
What's best practice for this?
Thanks

My first stop would be the Expect module. I'm not sure if I'd need a second stop after that.

Related

Respond Y dynamically to a shell program

We have a startup script for an application (Owned and developed by different team but deployments are managed by us), which will prompt Y/N to confirm starting post deployment. But the number of times it will prompt will vary, depends on changes in the release.
So the number of times it will prompt would vary from 1 to N (Might be even 100 or more than that).
We have automated the deployment and startup using Jenkins shell script jobs. But startup prompts number is hardcoded to 20 which might be more at sometime.
Could anyone please advise how number of prompts can be handled dynamically. We need to pass Y whenever there is pattern in the output "Do you really want to start".
Checked few options like expect, read. But not able to come up with a solution.
Thanks in advance!
In general, the best way to handle this is by (a) using a standard process management system, such as your distro's preferred init system; or, if that's not possible, (b) to adjust the script to run noninteractively (e.g., with a --yes or --noninteractive option).
Barring that, assuming your script reads from standard input and not the TTY, you can use the standard program yes and pipe it into the command you're running, like so:
$ yes | ./deploy
yes prints y (or its argument) over and over until it's killed, usually by SIGPIPE.
If your process is reading from /dev/tty instead of standard input, and you really can't convince the other team to come to their senses and add an appropriate option, you'll need to use expect for this.

Is there a way to make a bash script process messages that have been sent to it using the write command

Is there a way to make a bash script process messages that have been sent to it using the "write" command? So for example, if a user wants to activate a feature in my script, could I make it so that they can send the script a command using the write command?
One possible method I thought of was to configure logging for a screen session and then have the bash script parse text through there, but I'm not sure if there would be a simpler or more efficient way to tackle this
EDIT: I was thinking as an alternative solution I could use a named pipe. I'm worried that it would break though if the tmp partition gets filled up completely (not sure if this would impact write as well?). I'm going to be running this script on a shared box, and every once in a while someone will completely fill up the /tmp partition and then just leave it like that until people start complaining
Hmm, you are trying to really circumvent a poor unix command to ask it something it was not specified for. From the man page (emphasize mine):
The write utility allows you to communicate with other users, by copying
lines from your terminal to theirs
That means that write is intended to copy line directly on terminals. As soon as you say, I will dump terminal output with screen, and then parse the dump file, you loose the simplicity of write (and also need disk space, with the problem of removing old lines from a sequencial file)
Worse, as your script lives on its own, it could (should?) be a daemon script attached to no terminal
So if I have correctly understood your question, your requirements are:
a script that does some tasks and should be able to respond to asynchronous requests - common usages are named pipes or network or unix domain sockets, less common are files in a dedicated folder with a optional signal to have immediate processing, adding lines to a sequential file while being possible is uncommon, because of a synchonization of access problem
a simple and convivial way for users to pass requests. Ok write is nice for that part, but much too hard to interface IMHO
If you do not want to waste time on that part by using standard tools, I would recommend the mail system. It is trivial to alias a mail address to a program that will be called with the mail message as input. But I am not sure it is worth it, because the user could directly call the program with the request as input or command line parameter.
So the client part could be simply a program that:
create a temporary file in a dedicated folder (mkstemp is your friend in C or C++, or mktemp in shell - but beware of race conditions)
write the request to that file
optionaly send a signal to a pid - provided the script write its own PID on startup to a dedicated file

Perl Interacting With Terminal

I'm not sure if what I am trying to do is possible, and I'm fairly new to perl so I'd appreciate any help.
My perl application will use system() to issue commands to Perforce that will create a devel/workspace, integrate, sync, etc. But obviously I can't integrate until my devel is created, and I can't sync unless some condition is met, so on and so forth. Also when my code is synced and I run it, I'm not sure how to tell if it finished or not either.
So I'm wondering how to say (slack pseudo code):
system(create my devel);
wait until devel created
system(integrate blah);
wait until integration complete
system (launch test);
wait until test complete;
etc...
I looked at other questions and saw the possibility of using forks, but I am not familiar with how to code that in this context.
Thanks
Normally, the system command in Perl will wait until the command you asked it to run has completed. This would work exactly the same as if you entered the command at a shell prompt, the program would run and the shell prompt would appear only when the command has completed whatever it is doing.
Perforce has a free Perl module downloadable from http://www.perforce.com/downloads/Perforce/20-User?qt-perforce_downloads_step_3=6#qt-perforce_downloads_step_3#52, with documentation at http://www.perforce.com/perforce/r12.1/manuals/p4script/02_perl.html#1047731.
But it sounds like you need more experience with Perl multiprogramming and IPC. Have you read the Camel book?

Linux non-su script indirectly triggering su script?

I'd like to create an auto-testing/grading script for students on a Linux system such that:
Any student user can initiate the script at any time.
A separate script (with root privileges) copies student code to a non-student-accessible file space, using non-student-accessible unit tests, etc.
The user receives limited feedback in the form of a text file generated by the grading script.
In short, I'm looking to create something similar to programming contest submission systems, but allowing richer feedback without revealing all teacher unit testing.
I would imagine that a spooling behavior between one initiating script and one root-permission cron script might be in order. Are there any models/examples of how one might best structure communication between a user-initiated script and a separate root-initiated script for such purposes?
There are many options.
The things I would mention at the first line:
Don't use su; use sudo; there are several reasons for it, and the main reason, that to use su you need the password of the user you want to be and with sudo — you don't;
Scripts can't be suid, you must use binaries or just a normal script that will be started using sudo (of course students must have sudoers entry that allows them to use the script);
Cron is not that fast, as you may theoretically need; cron runs tasks every minute; please consider inotify usage;
To communicate between components of your system you need something that will react in realtime; there are many opensource components/libraries/frameworks that could help you, but I would recommend you to take a look at ZeroMQ and Redis;
Results of the scripts' executions/tests can be written either to a filesystem (I think it would be better), or to a DBMS.
If you want to stick to shell scripting, the method I suggest for communicating between processes would be to have the root script continually check a named pipe for input (i.e. keep opening it after each eof) and send each input through whatever various tests must be done. Have part of the input be a 'return address' - where to send the result.
This should allow the tests to be performed in a privileged space without exposing any control over the privileged space to the students. The students don't need sudo, and you don't need to pull in libraries. Just have the students pipe their code into a non-privileged script that adds the return address and whatever other markup you may need, which then gives it to the named pipe.

Scp as background job?

Here is the problem:
i must move some files from one host to another, ok i use scp for
it.
But i need use it without blocking console, so should use scp &. But my job will killed after disconnecting (a heard it`s something called hup signal) so i found some tricks for fixing this.
But i wanna see progress bar after some time and all that tricks couldnt work because when i use jobs - it display jobs that only for these session.
So how to fix my problem ?
P.S. Sorry for my English.
I am not sure it is what you want but I'll suggest GNU Screen. It allows you to run a program so that when you log out, the program continues execution in the background. Later you can log back in and resume interaction with the program.
I guess you want ability to detach -and- attach terminal - The tool is called screen.

Resources