Escape sequence <ESC>]0; - expect

I am currently trying to write a script that uses expect to logon to SSH. Logging on to a server every prompt appears as [user#host]~/directory$ when I use a xterm color terminal. However, if I read the output from SSH directly with expect I see the following <ESC>]0;user#host:~/directory[user#host]~/directory$. Using export PS1="#-->" changes the result to <ESC>]0;user#host:~/directory#-->.
My question is: What does the sequence <ESC>]0;do? And which class of terminals does it belong to? I could not find it for neither VT52 nor VT100.

by default, the label of each tab is the name of the job that's running in that session. some systems are configured to augment this with additional information such as the hostname you're logged in to or your current directory; this is done by sending a special code of:
ESC]0;<string>^G
such as, ESC]0;david#Scott:~^G, would put "david#Scott:~" in my tab title
this is referred to as the XTERM hardstatus hack.

Related

Request user input in bash_profile alias command

Is there anyway to stop in a bash_profile alias command and prompt for a user input? I'm fairly new to writing terminal commands.
I'm making a custom command that will take 2 inputs and edit my host files and set up vhosts for me on my local machine, at the moment i'm just passing the arguments into the command
addSite mywebsite.co.uk
But ideally I would like to be able to just run addSite, then the command stops and prompts 'Please enter the domain for your new site'.
Is this possible? If not, can someone point me in the right direction to be able to write a custom terminal command that can do this?
Thanks
You can ask for user input with read and pass a prompt with the -p flag. After the command, you specify the variable name. Then access it like any other variable.
read -p 'Please enter the domain for your new site: ' domain
echo Your domain name: $domain
EDIT: as pointed out by #tripleee in the comments, it's worth noting that this will have unintended side effects if a shell is launched from another source e.g. if you launch an executable file from Finder.

Creating a GUI to interact with Putty

I have to build one application which on button click starts passing command with putty.exe how can it be done with process.start ?
Process.start(#"C:\putty.exe")
ProcessStartInfo startinfo = new ProcessStartInfo();
startInfo.FileName=#"C:\putty.exe"
startInfo.Arguments = "some load session";
this is my current code but i want to push certain script and commands to putty terminal as well
It looks like PuTTY's command line support is rather minimal, but the -m option may work:
From http://the.earth.li/~sgtatham/putty/0.67/htmldoc/Chapter3.html#using-cmdline
3.8.3.6 -m: read a remote command or script from a file
The -m option performs a similar function to the ‘Remote command’ box in the SSH panel of the PuTTY configuration box (see section 4.18.1). However, the -m option expects to be given a local file name, and it will read a command from that file.
With some servers (particularly Unix systems), you can even put multiple lines in this file and execute more than one command in sequence, or a whole shell script; but this is arguably an abuse, and cannot be expected to work on all servers. In particular, it is known not to work with certain ‘embedded’ servers, such as Cisco routers.
You'll have to put your command(s) in a file before and pass that to PuTTY, but for simple tasks, it could work.
As mentioned in a comment on the question, Plink sounds much more amenable to what you're trying to do, as it (appears to) support a fully interactive session via the StandardInput and StandardOutput properties on the object you'll get back from Process.Start().

How to execute a script in zsh and then become interactive?

I want to run a predetermined set of commands after the invocation of zsh (i.e. after .zshrc is executed) that returns the user to an interactive shell when complete.
Things like this comes to my mind:
urxvt -e 'zsh -c ". scriptname"'
but instead of exiting zsh and the terminal once the script finishes, I want an interactive shell at the end. The idea is to simply save users from having to type ". scriptname" whenever they log in.
Application: Several users are using the same account (strange but true) and I want to help in adjusting user specific settings. Yes, I know that one could use different accounts for that :-)
Not really what you were asking for, but should have the desired result. You use an environment variable to pass the name of the user-specific script to source to .zshrc (or other appropriate startup file).
urxvt -e 'USERSCRIPT=scriptname zsh'
Then in .zshrc for the actual user, include
. $USERSCRIPT
(All of this is not to say that there isn't an option to run a command then remain in interactive mode; I just can't find a way to do it, so I offer this workaround.)

Passing parameters to a SSH client to execute a ForceCommand with parameters

I'm having trouble passing command parameters remotely to a "ForceCommand" program in ssh.
In my remote server I have this configuration in sshd_config:
Match User user_1
ForceCommand /home/user_1/user_1_shell
The user_1_shell program limits the commands the user can execute, in this case, I only allow the user to execute "set_new_mode param1 param2". Any other commands will be ignored.
So I expect that when a client logs in via ssh such as this one:
ssh user_1#remotehost "set_new_mode param1 param2"
The user_1_shell program seems to be executed, but the parameter string doesn't seem to be passed.
Maybe, I should be asking, does ForceCommand actually support this?
If yes, any suggestions on how I could make it work?
Thanks.
I found the answer. The remote server captures the parameter string and saves it in "$SSH_ORIGINAL_COMMAND" environment variable.
As already answered, the commandline sent from the ssh client is put into the SSH_ORIGINAL_COMMAND environment variable, only the ForcedCommand is executed.
If you use the information in SSH_ORIGINAL_COMMAND in your ForcedCommand you must take care of security implications. An attacker can augment your command with arbitrary additional commands by sending e.g. ; rm -rf / at the end of the commandline.
This article shows a generic script which can be used to lock down allowed parameters. It also contains links to relevant information.
The described method (the 'only' script) works as follows:
Make the 'only' script the ForcedCommand, and give it the allowed
command as its parameter. Note that more then one allowed command may be used.
Put a .onlyrules files into the home directory of user_1 and fill it with rules (regular expressions) which are matched against the
commandline sent by the ssh client.
Your example would look like:
Match User user_1
ForceCommand /usr/local/bin/only /home/user_1/user_1_shell
and if, for example, you want to allow as parameters only 'set_new_mode' with exactly two alphanumeric arbitrary parameters the .onlyrules file would look like this:
\:^/home/user_1/user_1_shell set_new_mode [[:alnum:]]\{1,\} [[:alnum:]]\{1,\}$:{p;q}
Note that for sending the command to the server you must use the whole commandline:
/home/user_1/user_1_shell set_new_mode param1 param2
'only' looks up the command on the server and uses its name for matching the rules. If any of these checks fail, the command is not run.
[Disclosure: I wrote sshdo which is described below]
There's a program called sshdo for doing this. It controls which commands may be executed via incoming ssh connections. It's available for download at:
http://raf.org/sshdo/ (read manual pages here)
https://github.com/raforg/sshdo/
It has a learning mode to allow all commands that are attempted, and a --learn option to produce the configuration needed to allow learned commands permanently. Then learning mode can be turned off and any other commands will not be executed.
It also has an --unlearn option to stop allowing commands that are no longer in use so as to maintain strict least privilege as requirements change over time.
It can also be configured manually.
It is very fussy about what it allows. It won't allow a command with any arguments. Only complete shell commands can be allowed. But it does support simple patterns to represent similar commands that vary only in the digits that appear on the command line (e.g. sequence numbers or date/time stamps).
It's like a firewall or whitelisting control for ssh commands.

How can I flush the input buffer in an expect script?

I'm writing an Expect script and am having trouble dealing with the shell prompt (on Linux). My Expect script spawns rlogin and the remote system is using ksh. The prompt on the remote system contains the current directory followed by " > " (space greater-than space). A script snippet might be:
send "some command here\r"
expect " > "
This works for simple commands, but things start to go wrong when the command I'm sending exceeds the width of the terminal (or more precisely, what ksh thinks is the width of the terminal). In that case, ksh does some weird horizontal scrolling of the interactive command line, which seems to rewrite the prompt and stick an extra " > " in the output. Naturally this causes the Expect script to get confused and out of sync when there appears to be more than one prompt in the output after executing a command (my script contains several send/expect pairs).
I've tried changing PS1 on the remote system to something more distinctive like "prompt> " but a similar problem arises which indicates to me that's not the right way to solve this.
What I'm thinking might help is the ability for the script to tell Expect that "I know I'm properly synchronised with the remote system at this point, so flush the input buffer now." The expect statement has the -notransfer flag which doesn't discard the input buffer even if the pattern does match, so I think I need the opposite of that.
Are there any other useful techniques that I can use to make the remote shell behave more predictably? I understand that Expect goes through a lot of work to make sure that the spawned session appears to be interactive to the remote system, but I'd rather that some of the more annoying interactive features (such as the horizontal scrolling of ksh) be turned off.
If you want to throw away all output Expect has seen so far, try
expect -re $
This is a regexp match on $ which means the end of the input buffer, so it will just skip everything received so far. More details at the Expect man page.
You could try "set -o multiline" or COLUMNS=1000000 (or some other suitably large value).
I have had difficulty with ksh and Expect in the past. My solution was to use something other than
ksh for a login shell.
If you can change the remote login to other than ksh (using the chsh command or editing /etc/passwd) then you might try this with /bin/sh as the shell.
Another alternative is to tell KSH that the terminal is a dumb terminal - disallow it from doing any special processing.
$ export TERM=""
might do the trick.

Resources