BASH background process printings disappearing the prompt line - linux

I have a BASH script that runs on bg and print messages to the user when according to system events.
My problem is that after the echo of these messages, the user need to press on the ENTER key in order to get back to the prompt line.
Adding new line to the printed messages didn't help since it still comes from the bg and not from the user shell.
Does anyone have an elegant & simple solution to get the user back to the prompt line?
I will appreciate any help here..

You don't need to press enter to get to a prompt. You are still at the prompt that was there before the output was printed. Try just entering a command and hitting enter. (You can also hit ctrl-l to clear the screen instead of hitting enter to input an empty command.)
The problem here is that the background/alternative process has no relationship to the running shell session and so it is simply writing output to wherever the terminal sticks it. The process might be able to use control sequences to control the output location (but I don't know if this actually works).
Other than that there isn't much to be done about this that I'm aware of. And it isn't a problem in any real way.

Related

What are the linux signals that can be trapped in Tcl

I am working on a Tcl project where a certain procedure will run continuously. user can abort that procedure anytime using some Key-Combination. So basically, I need to trap the signal within Tcl code. So far, everything is done except one problem.
I am using Ctrl+Z i.e. SIGSUSP signal (SIGTSTP in case of Tcl) which technically does the job.
signal trap sigtstp onAbort
But, pressing Ctrl+Z immediately returns the Shell prompt, rest of the output from the program comes after that and when output comes to an end, no shell prompt returned (as it is already returned before). I need to press Enter again to get the prompt.
Following is the case I am refering to. You can see the prompt (polaris#ubuntu:~$) is returned in between output of the main program.
Also as output of pressing Ctrl+Z, it returned [40]+ Stopped, which is bit annoying. Can I avoid this ?
Can I avoid this whole problem using some other key-combination i.e. signal ? Or can I avoid this with Ctrl+Z also by tweking something ?
NOTE: I have tried using Ctrl+C. I got the exactly expected behavior with that. Unfortunately I can't use Ctrl+C as it is used for some other functionality.
Cz causes the shell to send the current foreground process a SIGSTOP(19). This signal cannot be caught or ignored and so your program will receive it and run the default handler. This is not killing the process as your question suggests you're trying to do. This only suspends it and you can bring it back into the foreground using fg on most modern shells.
Looks like you're out of luck. However, you might be able to rebind the keychord at the level of the shell. This is outside your program though and your end users don't have control over it. (Cf. https://superuser.com/questions/378018/how-can-i-do-ctrl-z-and-bg-in-one-keypress-to-make-process-continue-in-backgroun)
Also, if your program relies on user inputs for various actions (since you suggest that C-c does something else), perhaps you should make it a full fledged CUI application using curses or something?

Automate installation of binary in linux

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/

NodeJS Multiplexing Terminal?

Here's my issue. I'm outputting directly to console and also getting user input via the terminal. Sometimes, the user is typing a thing and then the text they were typing gets messed up when the console outputs something. It doesn't break the program, it's just annoying.
I looked at ncurses in the npm catalog, but it seems pretty complicated. All I want is to print stuff to the screen without disrupting user input.
Any help, and I do mean any help, is very much appreciated.
How are you reading from the terminal? If you're doing it in "raw" mode where you get input for each character (or each few characters), then when you get a character, set an "output inhibit" flag and also set a timeout that will clear the flag when the user has stopped typing for a bit. Whatever does your output needs to check the flag and hold off if it's set.
Alternatively, if the user is typing line-by-line, you could set the flag on each character and then clear it (and simply flush your output) when they enter a newline.
If the terminal is in "cooked" mode (your code doesn't see anything until the user types a newline) there's really little you can unless you bite the ncurses bullet.

Node command line interface change

I'm making a command interface for a node server, but I have reached a point that I want it to look better.
I want to have the console so you enter a command at the bottom of the terminal screen, you hit enter, and it adds the reply to the actual command line.
If you have ever run a minecraft bukkit server from the command line, you should know what I'm talking about.
Here's a picture of what I'm talking about if you still don't understand. Imagine this was in terminal, and ignore the scroll bars: http://cl.ly/1K0h1V0r0H3f3U3t3L22
Is there anyway to set the console to look like this without having to make your own program for it or having the screen reprint all the other info to fake that look?
I have not done this, but I believe something similar is possible with very little effort by using Node.js REPL. You can override the eval parameter to provide your own command processing.
It would not have the exact look you are wanting, but it will be an interactive prompt that you can utilize (more similar to a Windows command shell or a Linux shell).
If you want the exact look from your screenshot, I don't believe that there is any Node.js module that will help you. There are some that allow you to use colors in the console, and some basic highlighting (e.g. bold), but nothing that gives you complete control over the console screen.

Run a command in a shell and keep running the command when you close the session

I am using Putty to connect to a remote server. What I want to know is if there is any way to write my commands and allow them to keep running after I close the session with Putty. The reason for this is that I do not want to keep the computer ON all the time. Is there any way to do this?.
Update with the solution
For my question as it is presented the best solution is use one of the commands provided such as nohup, because you do not have to install any additional software. But if you are in the same problem use screen, install it and use it. It is amazing.
I have selected the answer of Norman Ramsey as favourite because propose several solutions using commands and screen. But please check the other answers specially the one of PEZ, then you get an insight of what screen is able todo.
screen! It's the best thing since sliced bread. (Yeah, I know others have already suggested it, but it's so good the whole world should join in and suggest it too.)
screen is like, like, ummmm ... like using VNC or the like to connect to a GUI destop, but for command shell windows. You can have several shell "windows" open at once in the same screen session. You can do stuff like:
Start a screens session using "screen -dR" (get used to using -dR)
run some commands in one window
press CTRL-A,C to create a new window open a file there in vim
press CTRL-A,0 to go back to the first window and issue some command on the file you just edited
CTRL-A, 1 to go back to your vim session
CTRL-A, C for yet another window and maybe do "sudo - su" (because you just happen to need a full root shell)
CTRL-A, 0 and start a background process
CTRL-A, C to create yet a new window, "tail -f" the log for that background process
CTRL-A, d to disconnect your screen then CTRL-D to disconnect from the server
Go on vacation for three weeks
Log on to the server again and issue "screen -dR" to connect to your existing screen session
check the log in the the fourth window with CTRL-A, 3 (it's like you've been there watching it all the time)
CTRL-A, 1 to pick up that vim session again
I guess you're starting to get the picture now? =)
It's like magic. I've been using screen for longer than I can remember and I'm still totally amazed with how bloody great it is.
EDIT: Just want to mention there's now also tmux. Very much like screen, but has some unique features, splitting the windows being the most prominent one.
nohup, disown, and screen are all good but screen is the best because unlike the other two, screen allows you to disconnect from the remote server, keep everything running, and then reconnect later to see what is happening. With nohup and disown you can't resume interacting.
Try using GNU Screen. It allows you to have several shells open at once. And you can disconnect from those running shells (i.e. close session with Putty) and they will keep doing their thing.
What you are looking for is nohup.
See the wiki link for how to use it.
screen is the best.
Try:
screen -dmS "MyTail" tail -f /var/log/syslog
This start command in background.
Use screen -r to list, and or screen -r Mytail to enter session.
If more users need access same session, use: screen -rx MyTail, and both or more users share the session.
If you can't use screen (because, for instance, your SSH session is being programmatically driven), you can also use daemonize to run the program as a daemon.
One way that works well for me is at.
at works like cron, but for a one-time job. I used it today to download a large file without having to keep my session alive.
for example:
$ at 23:55
at> wget http://file.to.download.com/bigfile.iso
at> ^D
You pass at a time (in the future) and it gives you a prompt. You enter the commands you want to run at that time and hit ctrl+d. You can exit out of your session and it will run the commands at the specified time.
Wikipedia has more info on at.
./command & disown
ssh localhost && ./command && exit

Resources