Inappropriate ioctl for device when trying to SSH - linux

I'm trying to SSH few servers and trying to get sudo -l output of each server.
Below is the script I'm executing
#!/bin/bash
serverlist="/tmp/servers"
while IFS=, read -r server netgroup username user
do
ssh -tt -q root#$server sudo -U $username -l < /dev/null
done < "$serverlist"
I have found that -tt option in this script as the cause of this error. Any thought on this?
Also i have noted that I don't see this error when i execute below command just for 1 server.
ssh -tt -q root#myserver sudo -U cham01 -l
Below is the complete error message I'am getting:
tcgetattr: Inappropriate ioctl for device

tcgetattr: Inappropriate ioctl for device normally means that some program attempted to do a terminal control operation but its standard I/O streams weren't connected to a terminal. (I know this because tcgetattr is the name of a C library function that does terminal control operations.)
Now, the whole point of the -tt option to ssh is to guarantee that the program run on the remote host is connected to a terminal, and stty printing out speed 38400 baud; line = 0; -brkint -imaxbel demonstrates that it was. This is what I get when I run these commands with my servers:
$ ssh myserver stty < /dev/null
stty: 'standard input': Inappropriate ioctl for device
$ ssh -tt myserver stty < /dev/null
speed 38400 baud; line = 0;
-brkint -imaxbel
Connection to myserver closed.
But what you are getting is
$ ssh -tt yourserver stty < /dev/null
tcsetattr: Inappropriate ioctl for device
speed 38400 baud; line = 0;
-brkint -imaxbel
The tcsetattr error is not coming from stty. First something tried to do something terminal-related and failed, and then stty ran successfully.
This suggests a bug in your shell startup scripts, which are doing something that is inappropriate when run "non-interactively", causing you to get this error even though you are running commands connected to a terminal. I can't help you any further, but perhaps this old answer about a similar problem offers some clues.

export GPG_TTY=$(tty)
From: https://github.com/keybase/keybase-issues/issues/2798#issue-205008630
:)

In this answer I will not propose a solution (I don't know where the error comes from) but, instead, I am going to suggest a powerful instrument to find it!
To understand where the problem comes from you can use the command strace:
strace ssh -tt -q root#myserver sudo -U cham01 -l < /dev/null
Sure you will realize which one is the system call that causes the error. The shell will prompt all the system calls and, at some point close to the end,you will see something like:
....
ioctl(3, SNDCTL_TMR_START or TCSETS, {B0 -opost -isig -icanon -echo ...}) = -1 ENOTTY (Inappropriate ioctl for device)
....
Here, you can find examples on how to use it.
Suggestion: before the ioctl(...) system call, there should be an open(...) system call for the same device. Go in the header file of the device and try to have a look on the different command you can pass it. The problem should be a not recognized command (due maybe to an old version of the device driver used). This is just a suggestion.

Related

Reading from a USB device using bash and raspberry pi 3?

I'm trying to catch the response from a device that is connected to the USB.
With this code:
sudo stty -F /dev/ttyUSB0 speed 115200 cs8 -cstopb -parenb -echo
sudo stty raw; cat > /home/received.log < /dev/ttyUSB0
echo "Monitor started"
On port ready, send the command request to the device
echo -en '\x5A\x00\x00\x0D\x0A\x71' > /dev/ttyUSB0
then read the log and paste the response in another file converting it properly
xxd -plain /home/received.log > /home/output.txt
so I can show the data,
cat -v < /home/output.txt
But I'm needing something more stable, that code is showing me this error:
stty: 'standard input': Inappropriate ioctl for device
which is weird, because it was working...
I would like to catch the response and store it in a variable.
i suggest getting rid of the stty raw.
Unless you are sending/receiving special characters that the tty subsystem will process, which is unlikely - because you said it is working - you almost certainly won't need it.
If it did work, you might find some undesirable side effects such as:
backspace does not erase a character that you miss-typed
control-c won't terminate your process
and other things that you might rely on in your terminal session.
FWIW, i am doing a similar thing with Arduino to Mac, Windows (cygwin) & Linux (read from the usb/serial port) and i have not been tempted to stty raw in any of those environments.

Send tee command via ssh

I send a tee command from host 1 to host 2:
ssh user#host2 '/path/run |& tee myFile.txt'
I use tee so that I get the output of the binary to be added to myFile.txt
The problem I have then is after a bit of time, I want to regain control of my local host without having a lot of printout. So I do CTRL+C. This lets the process on host2 continue to run, which is what I want, but it stops the tee process itself, so the file is not populated.
I tried to replace |& tee myFile.txt' by 2>&1 myFile.txt' & but it did not help.
How can I ensure that the file continues to be populated on host2, while regaining control to my session on host1?
If you want to record the results in some file (work with IO redirection inside of the nohup), you need to enclose all the pipeline in the nohup. It does not use shell expansions, since argument is only COMMAND ARGS, so using a sh is a good way:
ssh user#host2 'nohup sh -c "/path/run |& tee myFile.txt" &'
but note that nohup will disconnect the terminal from the command ant it might fail. Useful would be to redirect it directly to the file:
ssh user#host2 'nohup sh -c "/path/run &> myFile.txt" &'
Inspiration from the SO answer.
use nohup, screen or tmux for backgrounding a process.

echo command to serial port in Linux

I want to echo something from my Ubuntu host to some device.
It works well if I use putty or minicom.
However, it doesn't work if I do echo from the shell terminal:
echo "cmd" > /dev/ttyUSB0
From my device, I saw that the first letter of the cmd is received correctly while the second one received is ASCII bigger than 200. I also have tried to use the "stty" command to adjust the serial communication settings but didn't help. Does anythone know why?
Thanks,
First You need to set the tty device settings and then you need to transmit the data whatever you want
stty -F /dev/ttyUSB0 9600 -parity cs8 -cstopb
OR
stty -speed 9600 < /dev/ttyUSB0
Now Send data:
echo "cmd" > /dev/ttyUSB0

Getting stty: standard input: Inappropriate ioctl for device when using scp through an ssh tunnel

Per the title, I'm getting the following warning when I try to scp through an ssh tunnel. In my case, I cannot scp directly to foo because port 1234 on device foo is being forwarded to another machine bar on a private network (and bar is the machine that is giving me a tunnel to 192.168.1.23).
$ # -f and -N don't matter and are only to run this example in one terminal
$ ssh -f -N -p 1234 userA#foo -L3333:192.168.1.23:22
$ scp -P 3333 foo.py ubuntu#localhost:
ubuntu#localhost's password:
stty: standard input: Inappropriate ioctl for device
foo.py 100% 1829 1.8KB/s 00:00
Does anyone know why I might be getting this warning about Inappropriate ioctl for device?
I got the exact same problem when I included the following line on my ~/.bashrc:
stty -ixon
The purpose of this line was to allow the use of Ctrl-s in reverse search of bash.
This gmane link has a solution: (original link dead) => Web Archive version of gmane link
'stty' applies to ttys, which you have for interactive login sessions.
.kshrc is executed for all sessions, including ones where stdin isn't
a tty. The solution, other than moving it to your .profile, is to
make execution conditional on it being an interactive shell.
There are several ways to check for interecative shell. The following solves the problem for bash:
[[ $- == *i* ]] && stty -ixon
Got the same issue while executing the script remotely. After many tries didn't get any luck to solve this error. Then got an article to run a shell script through ssh. This was an issue related to ssh, not any other command. ssh -t "command" -t will allocate a pseudo TTY to the ssh and this error won't come.
at the end i created a blank .cshrc file ( for ubuntu 18.04). worked

SSH: guarding stdout against disconnect

My server deployment script triggers a long-running process through SSH, like so:
ssh host 'install.sh'
Since my internet connection at home is not the best, I can sometimes be disconnected while the install.sh is running. (This is easily simulated by closing the terminal window.) I would really like for the install.sh script to keep running in those cases, so that I don't end up with interrupted apt-get processes and similar nuisances.
The reason why install.sh gets killed seems to be that stdout and stderr are closed when the SSH session is yanked, so writing to them fails. (It's not an issue of SIGHUP, by the way -- using nohup makes no difference.) If I put touch ~/1 && echo this fails && touch ~/2 into install.sh, only ~/1 is created.
So running ssh host 'install.sh &> install.out' solves the problem, but then I lose any "live" progress and error output.
So my question is: What's an easy/idiomatic way to run a process through SSH so that it doesn't crash if SSH dies, but so that I can still see the output as it runs?
Solutions I have tried:
When I run things manually, I use screen for cases like this, but I don't think it will be of much help here because I need to run install.sh automatically from a shell script. Screen seems to be made for interactive use (it complains "Must be connected to a terminal.").
Using install.sh 2>&1 | tee install.out didn't help either (silly of me to think it might).
You can redirect stdout/stderr into install.out and then tail -f it. The following snippet actually works:
touch install.out && # so tail does not bark (race condition)
(install.sh < /dev/null &> install.out &
tail --pid "$!" -F install.out)
But surely there must a less awkward way to do the same thing?
Try using screen:
screen ./install.sh
If your ssh session gets interrupted, you can simply reattach to the session via another ssh connection:
screen -x
You can provide a terminal to your ssh session using the -t switch:
ssh -t server screen ./install.sh
install.sh 2>&1 | tee install.out
if the only issue is not getting stderr. You didn't say exactly why the tee wasn't acceptable. You may need the other nohup/stdin tweaks.

Resources