I very frequently work on multiple items in parallel and end up running some long tests or regression after working on something. I usually add a mail -s "foo" id < /dev/null at the end to know when a task ends so that I don't have to baby sit a long test or regression.
I was trying to automate this, where in I don't have to type the mail every time, just call a script (alias this to fewer characters - optimizing on how much I type) and the script figures out the test/regression from the cwd and sends an email. I thought it would be useful to send the terminal title or the screen session name in the email. Is there a way I can extract the terminal title or Linux screen window name?
You can find the screen session name, when attached, in $STY (the window number is available in $WINDOW if you need it):
$ echo "$STY"
6367.sessionname
You can find the uniquely identifying tty/pty device with tty:
$ tty
/dev/pts/34
Titles and such are features of xterm and not of the terminal itself, so terminals programs have a hard time deducing it.
Here's an example using both of the above to show the screen name if any, or the tty device otherwise:
mail -s "${STY:-$(tty)} done" < /dev/null
Screen also has a "wait for silence" feature where you can get a notification when processes in other screen windows have stopped outputting.
Related
I have a LiveCode app standalone that needs to know if there is a job waiting in the MacOS print queue before printing. If app user 1 prints the 2 page report and just one page prints (out of paper) then user 2 comes along and prints the report, the first page out is user 1's report and this is causing mixups. I would like to check the MacOS print queue and prevent printing if there is a job already waiting.
It's not something I've ever needed to do, but I suspect that this capability is not included in LiveCode natively. Instead your best bet will probably be to use LiveCode's shell() function to run a unix terminal command. For instance, lpstat is a command line utility that allows you to query various things about printers connected to your Mac. The following command, run in the MacOS terminal, shows which printers are available and their current status.
lpstat -p
In LiveCode you use the shell() function to call this command line utility, like so:
put shell("lpstat -p") into tPrinterStatus
To find out more about lpstat, open the Terminal and look up the man page:
man lpstat
Lots of options for that utility will appear. There should be one that gives you the information you need.
I have a script that runs a program that generates an email and then waits for the user to input information from that email. Because of this, the information is not available to pipe to the program on execution. It has to be done after it's running already.
I've tried a number of the different method suggestions, redirecting to the terminal (echo or cat > /dev/pts/#), mkfifo, expect, etc. Most of these methods are successful in actually sending the information to the target terminal - I actually see the information show up there. But there doesn't seem to be a way to send the equivalent of someone pressing the enter key.
Newline (using echo -en) or \n inside of the information send actually makes the cursor move in the target terminal - but it's not the same as actually pressing enter. It just scrolls the screen down one line. If I select the terminal window and press enter, it then accepts the input.
How can I do this from a different terminal (or can I?)
Or better yet, is there a way from the same script that's launched the program now waiting for input to send the program input?
Most of what I've seen has gone the route of using another terminal to try to send the information to the program.
Flow:
Simple similar example is if you were running a shell script that during its execution, runs a program that generates a PIN sent to your email, and then waits for the PIN to be entered before continuing.
In terminal 1, a bash script is run - one of the steps this script does is launch a program that generates an email and then sits at a prompt, waiting for the user to provide input (data from the email sent).
In terminal 2 (or if you can do this through terminal 1 somehow), take the value from the email and input it to the program in terminal 1, including pressing the enter key, so the program sees this value as actually entered and the program can complete its execution.
script in terminal 1:
...
if [ -f $progamToRun ]; then
$programToRun # This program sends the email and prompts the user for information from the email. It waits here...
# once information from email is entered, continue executing commands here
fi
script in terminal 2:
...
# monitor email
# retrieve information from email
# send information to program in terminal 1 that is waiting for this input
# exit script
The steps for the script in terminal 2 are working - and all of the methods I've tried to send the information to the program in terminal 1 haven't worked - that is to say, even if the information appears in the terminal through STDIN, etc. the application running doesn't recognize it as input so it's still sitting in the wait state.
I attempted to use netcat as suggested, but that's failing differently.
In terminal 1 I ran:
cat /tmp/nctest | /tmp/docl.sh -i 2>&1 | nc -l 127.0.0.1 8080 > /tmp/nctest
docl.sh contains one line, the application I am running to generate the email and wait.
In terminal 2 I ran:
nc 127.0.0.1 8080 <information from email>
When I run this in terminal 2, I immediately get the error from the program run in the script in terminal 1 that it failed. I tried this:
nc 127.0.0.1 8080
by itself to see if there was an issue passing the information on the same line I run nc, but get the same result. It's like the first terminal's nc command actually runs the application and then somehow bypasses or processes the prompt, so it's gone before I can enter the information from the email.
I also tried the command in terminal 1 without the -i and without the 2>&1, but there was no difference in the result.
When I log onto my assorted PCs I usually have a number of things I want to happen automatically, but not always straight away.
These include starting terminal sessions in specific locations on specific desktops (because you get used to using the same layout) and those terminal sessions performing specific acts such as ssh commands. However sometimes when you logon after a reboot you may not want to execute those commands immediately as a higher priority action may need your attention first.
So....what I want is my login script to open terminal sessions and have the session commands pre populated on the command line, but not yet executed.
I use Mate and Compiz as my DE as I like its flexibility.
So in my login script I currently have commands such as.....
mate-terminal --window-with-profile=default --geometry=85x24+180+400 --title='SSH1' &
mate-terminal --window-with-profile=default --geometry=85x24+180+1080 --title='VNC1' &
mate-terminal --window-with-profile=default --geometry=85x24+1305+400 --title='SSH2' &
mate-terminal --window-with-profile=default --geometry=85x24+1305+1080 --title='VNC2' &
These are dedicated mate-terminal sessions that I then enter a ssh and vnc command respectively to connect to some remote boxes. They always open in the same workspace and as can be seen open at a specific location so I always know exactly where I expect them to be.
However I don't want to use the option to say have the ssh command built into the script (as ssh is time sensitive to the receiver and I may not get to it straight away), instead I want to have the command already pre populated in the terminal session so when I do get to it I don't have to type in the whole command each time.
I had looked at using expect to do this and have that working thus
#!/usr/bin/expect -f
# Get a bash shell
spawn -noecho bash
# wait for a prompt
expect ">:"
# type something
send "ssh root#192.168.1.1"
# Hand over control
interact
exit
however I can't see a way of using expect that allows me to spawn the mate-terminal session at specific geometry locations (possibly I'm missing something obvious as I haven't used expect before).
I also don't want to autologon to the ssh sessions using something like a bash 'mate-terminal -c' option as at times the machine may not be network connected which means I'll have a load of potentially messed up attempted connects.
So in recap.
Bash login script.
Opens mate-terminal session at specific geometry locations with command line pre populated with desired command but not yet executed.
Ideas?
I have a Bourne-Again shell script text executable named engine.bin that I want to install.
If I install the executable manually ./engine.bin I get a screen with the EULA I have to accept (by pushing space), then accept it by writing yes and then enter the installation path by typing /usr/local/engine.
Now I want to do the installation automatically through provisioning scripts without manual interaction. Is there a way to do this? I do not know if the installer accepts any parameters, unfortunately the thing is undocumented.
Based on the suggestion of bill-agee and jgr208 I wrote the following which is working for me:
#!/usr/bin/expect -f
set timeout -1
spawn /tmp/engine.bin
expect {
-gl "*Press SPACE or PAGE DOWN key to continue, U or PAGE UP key to scroll back*" { send -- " "; exp_continue }
-gl "*yes/no*"
}
send -- "yes\r"
expect -gl "*press ENTER to accept the default*"
send -- "/tmp/tce\r"
expect eof
If the executable allows you to spam input at it without waiting for each separate prompt to appear, you might be able to accomplish this with bash.
For example, this script will run program_that_takes_several_lines_of_input.py and send it four lines of input - three with text and one blank line:
#!/bin/bash -eux
./program_that_takes_several_lines_of_input.py <<EOD
first line
one enter keypress later
yet another line of input after the empty line above
EOD
If you need to stop and wait for each prompt to appear, the cram Python package may be a good fit for this scenario - I find it useful for tasks like this where you only need to send a few lines of input, but each line of input is different.
See:
https://bitheap.org/cram/
https://pypi.python.org/pypi/cram
Expect would also work, but I find that I reach working solutions a bit faster when using cram than with Expect.
pexpect is a great choice as well! See:
https://pexpect.readthedocs.org/en/stable/
I have a program, lets call if 'foo'
Foo works fine for a random amount of time during which it announces its progress on the console.
But after sometimes it stops giving any output. At this point I have to manually close the program (ctrl + c) and start it again.
I would like to know if there is a way to monitor console output of a program and in case there is no output for a certain duration of time take some action.
Platform is linux.
I've found this on Internet about a command called watch.
Name
watch - execute a program periodically, showing output fullscreen
Synopsis
watch [-dhvt] [-n ] [--differences[=cumulative]] [--help] [--interval=] [--no-title] [--version]
Description
watch runs command repeatedly, displaying its output (the first screenfull). This allows you to watch the program output change over time. By default, the program is run every 2 seconds; use -n or --interval to specify a different interval.
The -d or --differences flag will highlight the differences between successive updates. The --cumulative option makes highlighting "sticky", presenting a running display of all positions that have ever changed. [...]
watch will run until interrupted.