This question already has answers here:
Are shell scripts sensitive to encoding and line endings?
(14 answers)
Closed 4 years ago.
I have a shell script with a command that seems like it should work, but instead it fails with an odd wrapped/truncated/corrupted error message. Example:
$ ls -l myfile
-rw-r----- 1 me me 0 Aug 7 12:36 myfile
$ cat myscript
ls -l myfile
$ bash myscript
: No such file or directory
The file clearly exist, but even if I didn't, this is the kind of error message I would normally get:
$ ls -l idontexist
ls: cannot access idontexist: No such file or directory
Notice how it includes the tool name ls, a message string and the filename while mine does not.
Here's what I get if I try to use mysql instead. The error message looks like it's been wrapped, and now starts with a quote:
Command: mysql -h myhost.example.com
Expected: ERROR 2005 (HY000): Unknown MySQL server host 'myhost.example.com' (0)
Actual: ' (0) 2005 (HY000): Unknown MySQL server host 'myhost.example.com
And here's my trivial ssh command that should work, or at least give a normal error message, but which instead is wrapped to start with a colon and ends with strange clobbering:
Command: ssh myhost
Expected: ssh: Could not resolve hostname myhost: Name or service not known
Actual: : Name or service not knownname myhost
Why does this happen, and how do I fix it?
TL;DR: Your script or data has Windows style CRLF line endings.
Convert to Unix style by deleting the carriage returns.
How do I check if my script or data has carriage returns?
They're detectable as ^M in the output of cat -v yourscript:
$ cat -v myscript
ls -l myfile^M
If your script doesn't have them, your data might -- especially if reading from ini/csv files or curl:
hostname=$(curl https://example.com/loginhost.txt)
ssh "$hostname" # Shows strange error
echo "$hostname" | cat -v # Shows myhost^M
How do I remove them?
Set your editor to save the file with Unix line endings, aka "line terminators" or "end-of-line characters", and resave it.
You can also remove them from a command line with dos2unix yourscript or cat yourscript | tr -d '\r' > fixedscript.
If found in your data, you can pipe your source through tr -d '\r':
hostname=$(curl https://example.com/loginhost.txt | tr -d '\r')
Why do carriage returns cause strange error messages?
The "carriage return" character, aka CR or \r, causes the cursor to move to the start of the line, and continue printing from there. In other words, it starts overwriting the line from the start. This is why they wrap strangely:
Intended: ssh: Could not resolve hostname myhost\r: Name or service not known
Written: ssh: Could not resolve hostname myhost\r
Overwritten: : Name or service not known
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Result: : Name or service not knownname myhost
Related
As the question specifics ,i am getting this error while executing my bash script
In exact terms i get following error
bash: line 26: /dev/tty: No such device or address
bash: line 29: /dev/tty: No such device or address
Here are the concerned Line 26 and 29 in script respectively which causes the issue
read -e -p "Paste the links : " links </dev/tty
read -e -p "Enter your input : " sub </dev/tty
If someone wonders, i cannot simply remove writing to </dev/tty from line 26 and 29 , it causes different issues .. So basically i need fix or get alternative for writing to /dev/tty
I am executing my script by running -
curl raw_link | bash
Preferably i want a solution which only requires me to my edit my existing script .i don't want to run the script after saving it locally or execute it using any other way apart from curl raw_link | bash
ls -l /dev/tty returns the following
crw-rw-rw- 1 root root 5, 0 Aug 8 09:28 /dev/tty
ls -l </dev/tty returns the following
/bin/bash: /dev/tty: No such device or address
Also i would like to mention that this issue doesn't seem to be happening on every machine , i intend to use this script on Google Colab where i definitely do get this issue
To fix the bash error, you can try this workaround :
tty=$(readlink /proc/$$/fd/2)
read ... < $tty
$tty contains the actual tty device name.
I need in python execute this command and enter password from keyboard, this is works:
import os
cmd = "cat /home/user1/.ssh/id_rsa.pub | ssh user2#host.net \'cat >> .ssh/authorized_keys\' > /dev/null 2>&1"
os.system(cmd)
As you can see I want append public key to remote host via ssh.
See here: equivalent-of-ftp-put-and-append-in-scp and here: copy-and-append-files-to-a-remote-machine-cat-error
Of course I want it do it without user input I've try pexpect and I think command is to weird for it:
import pexpect
child = pexpect.spawn(command=cmd, timeout=10, logfile=open('debug.txt', 'a+'))
matched = child.expect(['Password:', pexpect.EOF, pexpect.TIMEOUT])
if matched == 0:
child.sendline(passwd)
in debug.txt:
ssh-rsa AAAA..........vcxv233x5v3543sfsfvsv user1#host1
/bin/cat: |: No such file or directory
/bin/cat: ssh: No such file or directory
/bin/cat: user2#host.net: No such file or directory
/bin/cat: cat >> .ssh/authorized_keys: No such file or directory
/bin/cat: >: No such file or directory
/bin/cat: 2>&1: No such file or directory
I see two solution:
fix command for pexpect, that it recognize whole string as one command or,
inject/write passwd to stdin as fake user, but how!?!?
From the pexpect docs:
Remember that Pexpect does NOT interpret shell meta characters such as
redirect, pipe, or wild cards (>, |, or *). This is a
common mistake. If you want to run a command and pipe it through
another command then you must also start a shell. For example::
child = pexpect.spawn('/bin/bash -c "ls -l | grep LOG > logs.txt"')
child.expect(pexpect.EOF)
That worked for me:
command = "/bin/bash -c \"cat /home/user1/.ssh/id_rsa.pub | ssh user2#host.net \'cat >> ~/.ssh/authorized_keys\' > /dev/null 2>&1\""
child = spawn(command=command, timeout=5)
This question already has answers here:
Are shell scripts sensitive to encoding and line endings?
(14 answers)
Closed 4 years ago.
I have a shell script with a command that seems like it should work, but instead it fails with an odd wrapped/truncated/corrupted error message. Example:
$ ls -l myfile
-rw-r----- 1 me me 0 Aug 7 12:36 myfile
$ cat myscript
ls -l myfile
$ bash myscript
: No such file or directory
The file clearly exist, but even if I didn't, this is the kind of error message I would normally get:
$ ls -l idontexist
ls: cannot access idontexist: No such file or directory
Notice how it includes the tool name ls, a message string and the filename while mine does not.
Here's what I get if I try to use mysql instead. The error message looks like it's been wrapped, and now starts with a quote:
Command: mysql -h myhost.example.com
Expected: ERROR 2005 (HY000): Unknown MySQL server host 'myhost.example.com' (0)
Actual: ' (0) 2005 (HY000): Unknown MySQL server host 'myhost.example.com
And here's my trivial ssh command that should work, or at least give a normal error message, but which instead is wrapped to start with a colon and ends with strange clobbering:
Command: ssh myhost
Expected: ssh: Could not resolve hostname myhost: Name or service not known
Actual: : Name or service not knownname myhost
Why does this happen, and how do I fix it?
TL;DR: Your script or data has Windows style CRLF line endings.
Convert to Unix style by deleting the carriage returns.
How do I check if my script or data has carriage returns?
They're detectable as ^M in the output of cat -v yourscript:
$ cat -v myscript
ls -l myfile^M
If your script doesn't have them, your data might -- especially if reading from ini/csv files or curl:
hostname=$(curl https://example.com/loginhost.txt)
ssh "$hostname" # Shows strange error
echo "$hostname" | cat -v # Shows myhost^M
How do I remove them?
Set your editor to save the file with Unix line endings, aka "line terminators" or "end-of-line characters", and resave it.
You can also remove them from a command line with dos2unix yourscript or cat yourscript | tr -d '\r' > fixedscript.
If found in your data, you can pipe your source through tr -d '\r':
hostname=$(curl https://example.com/loginhost.txt | tr -d '\r')
Why do carriage returns cause strange error messages?
The "carriage return" character, aka CR or \r, causes the cursor to move to the start of the line, and continue printing from there. In other words, it starts overwriting the line from the start. This is why they wrap strangely:
Intended: ssh: Could not resolve hostname myhost\r: Name or service not known
Written: ssh: Could not resolve hostname myhost\r
Overwritten: : Name or service not known
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Result: : Name or service not knownname myhost
I'm on an RHEL server trying to SSH to a windows server using the following command -
ssh -p 5950 -i /home/svcacct/.ssh/serverkey svcacct#servername prog Alias=database add -a blah -p "var1=shared_data\Repost, var2=1771, var3=1000 - S&P Index Summary, var4=SP, var5=20150129"
It then fails with the following message -
'P' is not recognized as an internal or external command,
operable program or batch file.
The reason seems to be that linux is using the '&' as a special character which I don't want it to do.
It seems you forgot to escape some quotes:
ssh -p 5950 -i /home/svcacct/.ssh/serverkey svcacct#servername prog Alias=database add -a blah -p "var1=shared_data\Repost, var2=1771, var3=\"1000 - S&P Index Summary\", var4=SP, var5=20150129"
As per project requirement, i need to check the content of zip file generated which been generated on remote machine.This entire activity is done using automation framework suites. which has been written in shell scripts. I am performing above activity using ssh command abd execute unzip command with -l and -q switches. But this command is getting failed. and shows below error messages.
[SOMEUSER#MACHINE IP Function]$ ./TESTS.sh
ssh SOMEUSER#MACHINE IP unzip -l -q SOME_PATH/20130409060734*.zip | grep -i XML |wc -l
unzip: cannot find or open SOME_PATH/20130409060734*.zip, SOME_PATH/20130409060734*.zip.zip or SOME_PATH/20130409060734*.zip.ZIP.
No zipfiles found.
0
the same command i had written manually but that works properly. I really have no idea.Why this is getting failed whenever i executed via shell scripts.
[SOMEUSER#MACHINE IP Function]$ ssh SOMEUSER#MACHINE IP unzip -l -q SOME_PATH/20130409060734*.zip | grep -i XML |wc -l
2
Kindly help me to resolve that issue.
Thanks in Advance,
Priyank Shah
when you run the command from your local machine, the asterisk character is being expanded on your local machine before it is passed on to your remote ssh command. So your command is expecting to find SOME_PATH/20130409060734*.zip files on your machine and insert them into your ssh command to be passed to the other machine, whereas you (I'm assuming) mean, SOME_PATH/20130409060734*.zip files on the remote machine.
for that, precede the * character by a backslash ( \ ) and see if it helps you. In some shells escape character might be defined differently and if yours is one of them you need to find the escape character and use that one instead. Also, use quotes around the commands being passed to other server. Your command line should look something like this in my opinion:
ssh SOMEUSER#MACHINE_IP "/usr/bin/unzip -l -q SOME_PATH/20130409060734\*.zip | grep -i XML |wc -l"
Hope this helps