plink truncating commands - bash

I'm using plink.exe on WinXP to run some commands on Z/OS BASH. My commands are interspersed with echo commands so that I can parse the output and work out what is where. The first dozen or so commands run fine, but then one of them gets truncated.
For example:
echo :end_logdetail:
echo Job Name : TfmMigration
echo :jobinfo:
What happens:
user#host:/dev> echo :end_logdetail:
:end_logdetail:
user#host:/dev> echo Job Name : Tf
Job Name : Tf
user#host:/dev> echo :jobinfo:
:jobinfo:
I just checked where in the input file the error occurs, and it's exactly 4444 bytes in, on line 116 (so it's done 115 successful commands before it goes wrong). The command I'm using is:
Code:
plink -batch -pw xxxx user#host < "c:\dev\telnetcmd.txt" > "c:\dev\telnetout.txt"
The telnetcmd.txt is just a DOS text file with an "exit" command at the end.
Any idea why one of my commands is being truncated in this way?
Update: I don't get the problem if I pass the command file to plink with -m, only when I feed it in with the < operator.

As shellter points out, I should have been using the -m option. This does mean that (unlike the telnet solution that I was using) my commands do not show up in the output, and neither do the shell prompts, but I can manage without those.

Related

Logging into server (ssh) with bash script

I want to log into server based on user's choice so I wrote bash script. I am totally newbie - it is my first bash script:
#!/bin/bash
echo -e "Where to log?\n 1. Server A\n 2. Server B"
read to_log
if [ $to_log -eq 1 ] ; then
echo `ssh user#ip -p 33`
fi
After executing this script I am able to put a password but after nothing happens.
If someone could help me solve this problem, I would be grateful.
Thank you.
The problem with this script is the contents of the if statement. Replace:
echo `ssh user#ip -p 33`
with
ssh user#ip
and you should be good. Here is why:
Firstly, the use of back ticks is called "command substitution". Back ticks have been deprecated in favor of $().
Command substitution tells the shell to create a sub-shell, execute the enclosed command, and capture the output for assignment/use elsewhere in the script. For example:
name=$(whoami)
will run the command whoami, and assign the output to the variable name.
the enclosed command has to run to completion before the assignment can take place, and during that time the shell is capturing the output, so nothing will display on the screen.
In your script, the echo command will not display anything until the ssh command has completed (i.e. the sub-shell has exited), which never happens because the user does not know what is happening.
You have no need to capture the output of the ssh command, so there is no need to use command substitution. Just run the command as you would any other command in the script.

linux - bash: pipe _everything_ to a logfile

In an interactive bash script I use
exec > >(tee -ia logfile.log)
exec 2>&1
to write the scripts output to a logfile. However, if I ask the user to input something this is not written to this file:
read UserInput
Also, I issue commands with $UserInput as parameter. These command are also not written to the logfile.
The logfile should contain everything my script does, i.e. what the user entered interactively and also the resulting commands along with their output.
Of course I could use set -x and/or echo "user input: "$UserInput, but this would also be sent to the "screen". I dont want to read anything else on the screen except what my script or the commands echo.
How can this be done?

Capture Shell Script Output and Do a String Match to execute the next command?

i have a Shell script doing the following two commands, connecting to a remote server and putting files via SFTP, lets called it "execute.sh"
sftp -b /usr/local/outbox/send.sh username#example.com
mv /usr/local/outbox/DD* /usr/local/outbox/completed/
Then in my "send.sh" i have following commands to be executed on the remote server.
cd ExampleFolder/outbox
put Files_*
bye
Now my problem is
If the first command "sftp -b" fails due to a remote connection error some network problem, it still moves the files into the "completed folder" which is incorrect, so i want some way to do the next command "mv" to be executed only if the first command to "sftp" is successfully connected.
Can we do this by enhancing this shell script ? or some work around ?
My Shell is Bash.
Simply insert && between the two commands:
sftp -b /usr/local/outbox/send.sh username#example.com && \
mv /usr/local/outbox/DD* /usr/local/outbox/completed/
If the first fails, the second one will not run.
Alternatively, you can check the exit code of the first command explicitly. The exit code of the last command is always saved in $?, and it is 0 if the command succeeded:
sftp -b /usr/local/outbox/send.sh username#example.com
if [ $? -eq 0 ]
then
mv /usr/local/outbox/DD* /usr/local/outbox/completed/
fi
If you really wanted to capture the output of the first command, you could run it in $(...) and store the value in a variable:
sftpOutput="$(sftp -b /usr/local/outbox/send.sh username#example.com)"
and then use this variable in further checks, e.g. match it against a pattern in the next if.

How to combine batch file and expect script in cygwin?

i have an application on windows that requires user name and password to start, but i don't want user to enter the user/password, so i created a script to interact with CMD interface to enter the password, using cygwin on windows 8.1, but i can't find expect command on the Cygwin, and i would like to ask also if my script has any issue.
below is the script
#!/usr/bin/expect
sh C:\Users\Osama.Barakat\Desktop\batchfile.bat
expect "Enter the password for administrator:"
send "Pa$$w0rd"
interact
I identified two issues in your question:
How to perform batch files in cygwin/bash?
How to get expect installed/running in cygwin/bash?
1. How to perform batch files in cygwin/bash?
In your sample code, I found
---8<---
sh C:\Users\Osama.Barakat\Desktop\batchfile.bat
--->8---
IMHO, this is a mistake. I believe that bash will try to execute anything as script regardless of the script file extension. But if batchfile.bat is really a batch file then it should be called with the correct interpreter (i.e. cmd.exe) instead.
I tried it to see if there is any issue in the cygwin bash but it worked. My sample batch file test-expect.bat:
#echo off
rem output
echo Hello %USERNAME%
rem input
set /p INPUT= Enter input:
rem output
echo Input: %INPUT%
...tested in bash on cygwin:
$ cmd /c test-expect.bat
Hello Scheff
Enter input: Hello cmd
Input: Hello cmd
$
OK, done.
2. How to get expect installed/running in cygwin/bash?
To install expect on cygwin I googled a little bit and found Installation of Cygwin, expect and Ssh. Then, I started the cygwin-setup setup-x86.exe and tried something else:
On the "Select Packages" page, I set View to Full and Search to expect. I got a list of four entries only where the first was: "expect: Tool for automating interactive applications" (Category: Tcl). I choosed this for installation and had to confirm another package as dependency.
After installation, I tried this in an interactive bash:
$ which expect
/usr/bin/expect
$
OK - looks quite good.
Combining CMD.EXE and expect
To put all together, I wrote another test script test-expect.exp:
#!/usr/bin/expect
spawn cmd /c test-expect.bat
expect "Enter input: "
send "Hello expect\r"
interact
Tested in bash on cygwin:
$ ./test-expect.exp
spawn cmd /c test-expect.bat
Hello Scheff
Enter input: Hello expect
Input: Hello expect
$
Well, it seems to work.

Parsing SSH stream from batch

Using batch script to run ssh, I am finding all the output is dumped into the standard error... so my command:
ssh -i keyfile user#host "commands" 2> error.log
captures the remote server prompt for password if there are no matching keys in the local known_hosts...
This leaves me no way to capture the output for error processing or logging without leaving the user of my batch script stuck no knowing what the blank prompt is.
My other thought is to do a simple ssh to test the connection first and establish the password prompt if it's needed, then move to the command of interest. But I feel like if the first one passes, then the only thing I'm error is my remote command.
I've tried
>CON 2> error.log
... seems to do the same thing.
Unfortunately there's no TEE command default in Windows.
My best solution is to:
1) echo Enter password
2) ssh "params" 2>error.log
Suggestions?
If the remote system supports the syntax, you could do something like this:
ssh -i keyfile user#host "commands 2>&1" > output.log 2> error.log
This redirects the remote command's error output to its standard output. ssh's own standard output and standard error aren't affected. The 2>&1 part is Bourne shell syntax to redirect standard error (descriptor 2) to standard output (descriptor 1). It should work if the remote shell is sh, bash, or ksh.

Resources