Read several variables from command output via SSH

Hi Folks,

I'm currently trying to read several values into different variables.
Actually, what I'm doing works, but I get an error message.

My attempts are:

read strCPROC strIPROC strAPROC <<<$(ssh -n -T hscroot@$HMC "lshwres -r proc -m $strIDENT --level sys -F \"configurable_sys_proc_units installed_sys_proc_units curr_avail_sys_proc_units\"")
read strCPROC strIPROC strAPROC < <(ssh -n -T hscroot@$HMC "lshwres -r proc -m $strIDENT --level sys -F \"configurable_sys_proc_units installed_sys_proc_units curr_avail_sys_proc_units\"")

and both lead to the error message:

stty: standard input: Inappropriate ioctl for device

Can someone maybe help me to avoid this or maybe have another idea how to achieve that?

Thanks and kind regards,
Kaede

ssh calls stty to do things like turn off/on echo. When the terminal stdin device is not what ssh expected you get the stty error. Try simply executing the ssh command making sure it can use the controlling terminal device with stty and using ssh keys:

ssh me@somplace 'my command goes here ' > output_file
# output_file now has your result it in it,  so you can read the file to get your variables.

I may be missing something but this has happened to me before and my workaround was okay. Still is.

One caveat - if you are running under ksh (does appear to be in this case) then be sure there are no stty commands in the current directory's .kshrc , that also causes this problem.

try:

read strCPROC strIPROC strAPROC <<<$(ssh -n -T hscroot@$HMC "lshwres -r proc -m $strIDENT --level sys -F 'configurable_sys_proc_units installed_sys_proc_units curr_avail_sys_proc_units'"</dev/null)

The problem with that is, that I run these SSH commands in a while loop and the while loop breaks, when I don't use at least the -n parameter with ssh.
Here is the code block where I get the error.

24 for HMC in ${strHMCLIST}
25 do
26   strNILIST=""
27
28   ssh -n -T hscroot@$HMC "lssyscfg -r sys -F 'name type_model serial_num lpar_proc_compat_modes'" > .outlist.tmp
29   while read N T S P
30   do
31     strNAME=$N
32     strIDENT=$T'*'$S
33     strNILIST=$strNILIST$strNAME" "$strIDENT"\n"
34     strCPUARCH=${P##*,}
35
36     ssh -n -T hscroot@$HMC "lshwres -r proc -m $strIDENT --level sys -F 'configurable_sys_proc_units installed_sys_proc_units curr_avail_sys_proc_units'" > .outhw.tmp
37     read strCPROC strIPROC strAPROC < .outhw.tmp
38
39     ssh -n -T hscroot@$HMC "lshwres -r mem -m $strIDENT --level sys -F 'configurable_sys_mem installed_sys_mem pend_avail_sys_mem'" > .outhw.tmp
40     read strCRAM strIRAM strARAM < .outhw.tmp
41
42     echo -e "$strNAME,$T,$S,$strCPUARCH,$strIPROC,$strCPROC,$strAPROC,$strIRAM,$strCRAM,$strARAM" >> $strOUTPUTFILEHW
43   done < .outlist.tmp
44
45 done

I'm using the Cygwin bash
GNU bash, version 4.1.17(0)-release (i686-pc-cygwin)

Thanks, but it didn't help either.

Your code snippet does not look like what you showed in post #1. Where do you get the error? Is it issued by ssh or by lshwres ? Try changing -T to -t .

Split the problematic code into smaller pieces for a step by step trouble shooting; e.g. run the ssh command alone and check its output, then read a single value from a simple command into a single variable, then go on to more complex stuff. Is the IFS variable set correctly?

1 Like

The code snippet is already adjusted to jim mcnamara's suggestion, which unfortunately didn't solve the problem.
The error is caused by the ssh
-T and -t are doing the absolutely opposite thing.
Anyway, when I use -t , I only get another error.

Pseudo-terminal will not be allocated because stdin is not a terminal.

Which I can relate to.

Running every command for its own on the shell itself works perfectly, the codeblock itself also works as intended, I only get this error message from the ssh .
Running the ssh command on shell is also fine

# ssh -n -T hscroot@X.X.X.X "lshwres -r proc -m XXX --level sys -F 'configurable_sys_proc_units installed_sys_proc_units curr_avail_sys_proc_units'"; echo $?
16.0 16.0 10.0
0

EDIT:
IFS is set to single space, which also works fine.

Does lshwres interact directly with the terminal? Are there any options to disable this? I could sort of replicate the situation with stty :

ssh -n -t user@remotehost "hostname; stty"
Pseudo-terminal will not be allocated because stdin is not a terminal.
remotehostname
echo $?
0

No error!

Looks like -n and -t are mutually exclusive (which seems logical if reading the man page). Try dropping the -n:

ssh -t user@remotehost  "hostname; stty"
remotehostname
speed 38400 baud;
.
.
.
echo $?
0

Well, yes.

stty: standard input: Inappropriate ioctl for device
Pseudo-terminal will not be allocated because stdin is not a terminal.

Both outputs, aren't exactly errors, why the ssh command comes back with exit code 0.
I want to understand why this message comes and how I'm able to avoid it.

Like I said: The code is working perfectly, as it is supposed to be, I just receive this message and I try to build the script to avoid it properly and not just suppress it.

When I drop the -n parameter, the while loop will break, which is just how it is supposed to work.
The stty: standard input: Inappropriate ioctl for device message comes, regardless of which command I execute on the remote host, even a date, or test causes it, which is why I think that the ssh is responsible for it.

# ./script.sh
.
.
.
++ for HMC in '${strHMCLIST}'
++ strNILIST=
++ ssh -t hscroot@X.X.X.X 'lssyscfg -r sys -F '\''name type_model serial_num lpar_proc_compat_modes'\'''
++ read N T S P
Connection to X.X.X.X closed.
++ strNAME=XXX
++ strIDENT='XXX*XXX'
++ strNILIST='XXX XXX*XXX\n'
++ strCPUARCH=XXX
++ read strDATE
+++ ssh -t hscroot@X.X.X.X date
stty: standard input: Inappropriate ioctl for device
Pseudo-terminal will not be allocated because stdin is not a terminal.
++ read N T S P
++ echo

you said you're under Cygwin's bash.
Looks like Cygwin (at least mine) is using Windows' native ssh client:

 $ which ssh
/cygdrive/c/WINDOWS/System32/OpenSSH/ssh

Is that the case with you as well?
Any chance you can try the same script/steps on the native UNIX (not Cygwin on MS)?

Now, it doesn't break, that is. The ssh just eats up all stdin which is redirected from .outlist.tmp , and the while read cleanly finishes on end-of-file. Did you consider using another file descriptor for redirecting its input?

1 Like

You can connect the remote stdin to the local stdin if you use another descriptor for reading the file.

29   while read N T S P <&3
30   do
31     strNAME=$N
32     strIDENT=$T'*'$S
33     strNILIST=$strNILIST$strNAME" "$strIDENT"\n"
34     strCPUARCH=${P##*,}
35
36     ssh -t hscroot@$HMC "lshwres -r proc -m $strIDENT --level sys -F 'configurable_sys_proc_units installed_sys_proc_units curr_avail_sys_proc_units'" > .outhw.tmp
37     read strCPROC strIPROC strAPROC < .outhw.tmp
38
39     ssh -t hscroot@$HMC "lshwres -r mem -m $strIDENT --level sys -F 'configurable_sys_mem installed_sys_mem pend_avail_sys_mem'" > .outhw.tmp
40     read strCRAM strIRAM strARAM < .outhw.tmp
41
42     echo -e "$strNAME,$T,$S,$strCPUARCH,$strIPROC,$strCPROC,$strAPROC,$strIRAM,$strCRAM,$strARAM" >> $strOUTPUTFILEHW
43   done 3< .outlist.tmp
1 Like

I use MobaXterm, which brings its own SSH client.
Unfortunately, for "security reasons" this Windows Terminalserver is the only connection I have to my UNIX machines.

Well, yes, this works and is an idea I didn't get behind earlier.
Thank you very much!

Moderator comments were removed during original forum migration.