This is way out of date now
The information in this post is so out-dated that I wonder why I'm keeping it around. I guess I'm a digital hoarder...
So, you have some existing piece of software that really REALLY...I MEAN
REALLY wants its input on the command prompt. That is to say command <
/file/with/input
fails ya, and this particular piece of software does not have
a flag to include a setting you want (in this case it was a default user).
# Attempt Numero Uno
$ cat /my/input/file
awesome_user
SooPERsecRET
$ command < /my/input/file
ERR: Cannot continue in the background. Exiting
After some failed google-fu on ways to send stdin from a file, I had a headache
with pictures about using screen
.
JACK. POT.
Starting Our Screen
For scripting purposes, I needed to be able to reference the screen name
easily. I could have just parsed screen -ls
input, but I decided to RTFM
instead.
-S sessionname
When creating a new session, this option can be used to specify a meaningful name for the session. This name identifies the session for "screen -list" and "screen -r" actions. It substitutes the default [tty.host] suffix.
I also needed to be able to start in a detached state as I will want to run
this from a script eventually. Running screen &
inside a script was a no go.
-d -m
Start screen in "detached" mode. This creates a new session but doesn't attach to it. This is useful for system startup scripts.
Ok. So I can start a screen in a detached state with a useful name now.
screen -d -m -S automate_me
Sending Commands to the Screen
Back to the man pages!!!
-X
Send the specified command to a running screen session. You can use the -d or -r option to tell screen to look only for attached or detached screen sessions. Note that this command doesn't work if the session is password protected.
Now we can send the screen "stuff".
stuff [string]
Stuff the string string in the input buffer of the current window. This is like the "paste" command but with much less overhead. Without a parameter, screen will prompt for a string to stuff. You cannot paste large buffers with the "stuff" command. It is most useful for key bindings. See also "bindkey".
Put it all together. OH, and by the way, echo -ne '\015'
emulates pressing
the Enter key
(source).
$ screen -S automate_me -X stuff 'command'$(echo -ne '\015')
This might be easier to see when using an echo command. First, create your named detached screen and attach to it (or just create a named screen), then in a new terminal, run the command.
## Terminal 1
## Create a named screen
$ screen -S automate_me
## Terminal 2
$ screen -S automate_me -X stuff 'echo HELLO WORLD'$(echo -ne '\015')
You've just sent a command inside an existing screen session! HAPPY NOW?!
Coming back around to the original issue, you can use this to supply a username and password (probably not the most secure...but hey, we are learning)
$ screen -S automate_me -X stuff 'command'$(echo -ne '\015')
# The command would now be running in the screen, waiting for user input
# Now we supply said input
$ screen -S automate_me -X stuff 'echo awesome_user'$(echo -ne '\015')
$ screen -S automate_me -X stuff 'echo SooPERsecRET'$(echo -ne '\015')
Magical, isn't it.
THE END!!!
...I Lied!!
Turns out, this little trick acts REAL strange once you try automating it. I had some very inconsistent results while attempting to use this with my puppet manifests. (Things like it only worked if a user was actually attached to the screen session...making it not a very good option for automation)
Long story short, it was a good learning experience. PLUS, had I not gone down
this road, I would have never stumbled upon
expect
.