Skip to content

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.