Unexpected Shell Script errors [duplicate] - linux

This question already has an answer here:
Why would a correct shell script give a wrapped/truncated/corrupted error message? [duplicate]
(1 answer)
Closed 5 years ago.
I am having errors where I am putting in code that should be working fine into a shell file and when I run it, it fails to run correctly. The error I am receiving from this is confusing me as well somewhat. Here is what I have:
echo "Please enter your student ID: "
read username
echo "Please enter your MySQL password: "
read -s password
db="db$username"
echo "DB username is $db"
$(mysql -D$db -u$username -p$password -se "CREATE TABLE...")
echo "That has been completed"
The SQL command has been truncated as this appears to have no relevance for the error.
If I run this code through putty I get this:
*******#csl-*******:~/tasks/SQL$ ./generate.sh
Please enter your student ID:
': not a valid identifierad: `username
Please enter your MySQL password:
': not a valid identifierad: `password
DB username is db
ERROR 1045 (28000): Access denied for user '-p'#'localhost' (using password: NO)
./generate.sh: line 7: $'\r': command not found
That has been completed
*******#csl-*******:~/tasks/SQL$
(The * represent hidden values)
I am not sure what the error is with this code here. I have tried under different circumstances such as using a Mac to create the file with exactly the same file on and run it through terminal and it works fine (off the same Linux server). However I also went back to the same Mac to try and re-run the code and got the same error as shown here - even though the code hasn't changed.
Some background information:
Using Putty for SSH access, Filezilla for FTP, Sublime Text for code editor. Connecting to a remote Linux server to run from.

I think this is due to having the wrong line ending character, which would be the case if you are running sublime in windows.
Try running od -xcb to find the carriage return characters. Unix expects just \n whereas you will see \r\n with windows carriage returns.
You can fix your file by running dos2unix generate.sh.
As per Dannys comment below you can change the settings in sublime by going to view > line endings > unix.
Examples:
I copied your script and created a file using vim with unix carriage returns called script.sh. I then used unix2dos to create a file with windows carriage returns for testing and was able to recreate your error.
Unix carriage returns:
od -xcb script.sh
0000000 2123 622f 6e69 622f 7361 0a68 6365 6f68
# ! / b i n / b a s h \n e c h o
Windows carriage returns:
od -xcb windows.sh
0000000 2123 622f 6e69 622f 7361 0d68 650a 6863
# ! / b i n / b a s h \r \n e c h
And the error from the windows script:
> . windows.sh
Please enter your student ID:
': not a valid identifier
Please enter your MySQL password:
': not a valid identifier
DB username is db12
That has been completed

Related

Disabling echo service in Linux

Please, explain me what is echo service in Linux and how can I disable it?
For example, now I can type "echo hello" and it will print in the terminal "hello".
Thanks.
echo is a terminal command that simply prints its arguments to the console, as you observe.
man is another command which gives instructions on usage of a command. It stands for 'manual'. Therefore, to learn more about the echo command, you can run man echo.
It is not recommended to remove the echo command from your system, since it is part of GNU Coreutils, which is an essential part of the system. If you remove it, there is a high possiblity you may break your system.
However, you may remove it with:
$ su
# rm /bin/echo
The su command will prompt for the administrator password, and if correctly given, will put you in root. This is required because 'normal' users do not usually have permission to remove essential system components.
You can exit root with the exit command.
echo is a command used to print text to stdout. Normally this just means writing to your terminal as you mention:
$ echo 'Hello world'
Hello world
For more information on this command, you can read the manpage. Here is the output from my machine:
$ man echo
NAME
echo - echo - display a line of text
echo - display a line of text
Synopsis
echo [STRING]
Description
echo displays a string of text.
The following options are available:
· -n, Do not output a newline
· -s, Do not separate arguments with spaces
· -E, Disable interpretation of backslash escapes (default)
· -e, Enable interpretation of backslash escapes
· -h, --help Display this help
Escape Sequences
If -e is used, the following sequences are recognized:
· \\ backslash
· \a alert (BEL)
· \b backspace
· \c produce no further output
· \e escape
· \f form feed
· \n new line
· \r carriage return
· \t horizontal tab
· \v vertical tab
· \0NNN byte with octal value NNN (1 to 3 digits)
· \xHH byte with hexadecimal value HH (1 to 2 digits)
Example
echo 'Hello World' Print hello world to stdout
echo -e 'Top\nBottom' Print Top and Bottom on separate lines, using an escape sequence
As far as disabling it, I can't think of any good reason to do that. As was mentioned in the comments, you could delete or move the binary so that the command cannot be called, but that just seems to be a bad bad bad idea, so I won't even mention how to do that here.

What does this statement do on Linux?

I am trying to complete a lab report and I have just started using linux. I am really new to this ecosystem and I don't know how most of it works. I'm slowly learning from the labscript how to compile and execute C programs. However, after executing this statement
execute the output binary file using: $ ./myapp I am a student taking CMP 310
I lost the "$" sign and whenever I pressed enter this ">" would be printed before any statement and I couldn't execute or exit. If any of you could kindly explain what I did I would really appreciate it. Thank you.
You may have pasted an unmatched quote symbol, ' or " or a backtick ` and your terminal allows you to enter multiline statement and waits until you close the quote or backtick to evaluate it. To exit the multiline mode, either enter the closing character, or hit Ctrl-C, which in this case interrupts the input.
You have to paste only this part:
./myapp I am a student taking CMP 310
It tries to execute myapp executable file in your working directory (which ./ stands for), passing to it arguments I am a student taking CMP 310.
Me reproducing your problem:
16:45 $ "I have no idea what I am doing
> wut
>
>
> hello?
>
Most probably Ctrl+C will help you.
If you are working in GUI mode (not terminal) you can just close the window and open new shell session in new window.

Bash profile alias giving unexpected EOF and syntax errors

I'm trying to add the following alias in my .bash_profile in TextEdit in Mavericks (10.9.3) on a Mac Mini:
alias proj="cd ~/documents/google\ drive/web/projects"
I get the following errors:
line 1: unexpected EOF while looking for matching '"'
line 2: syntax error: unexpected end of file
bash gives:
alias proj='"cd'
However, if I copy & paste the exact same line from Notepad in my Windows VM into TextEdit it works..
bash now gives as expected:
alias proj='cd ~/documents/google\ drive/web/projects'
I've tried the following with no success:
Different paths with and without spaces
Swapped the Dell PC keyboard I was using for a Mac
Changed language to British English from British
Installed all updates
I can get round it using copy & paste as above, but would really like to get to the bottom of it. Any ideas much appreciated, thanks.
It is a quoting problem. Try:
alias proj="cd ~/documents/'google drive'/web/projects"
when eval-ing the alias command, the double quotes are removed.
When processing the "proj" invocation, the single quotes are removed.
Your original backslash was removed at alias evaluation time.
You could also double the backslashes:
alias proj="cd ~/documents/google\\ drive/web/projects"
Works for me. Turn on command tracing (set -x) and see what really happens.
$ cat xx ; source xx ; proj ; pwd
alias proj="cd $HOME/workspace/'google drive'/web"
/home/sciadmin/workspace/google drive/web
P.S. I sanity checked the equivalence of "$HOME" and "~" as an alias. Works fine, so replacing $HOME with ~ will work in the above example.
OK, here's the results for a symlink:
$ . xx ; cat xx ; proj ; pwd ; pwd -P
alias proj="cd ~/workspace/'google drive'/web"
/home/sciadmin/workspace/google drive/web
/home/sciadmin/workspace/foo bar/web
I think you may not be using BASH.
I had some issues with textedit and bash. Check textedit preferences 'GENERAL' and select plain text, then turn off smart quotes and smart dash.
If that doesn't do it - then, sadly, I am Sans Clue.

syntax error near unexpected token ' - bash

I have a written a sample script on my Mac
#!/bin/bash
test() {
echo "Example"
}
test
exit 0
and this works fine by displaying Example
When I run this script on a RedHat machine, it says
syntax error near unexpected token '
I checked that bash is available using
cat /etc/shells
which bash shows /bin/bash
Did anyone come across the same issue ?
Thanks in advance !
It could be a file encoding issue.
I have encountered file type encoding issues when working on files between different operating systems and editors - in my case particularly between Linux and Windows systems.
I suggest checking your file's encoding to make sure it is suitable for the target linux environment. I guess an encoding issue is less likely given you are using a MAC than if you had used a Windows text editor, however I think file encoding is still worth considering.
--- EDIT (Add an actual solution as recommended by #Potatoswatter)
To demonstrate how file type encoding could be this issue, I copy/pasted your example script into Notepad in Windows (I don't have access to a Mac), then copied it to a linux machine and ran it:
jdt#cookielin01:~/windows> sh ./originalfile
./originalfile: line 2: syntax error near unexpected token `$'{\r''
'/originalfile: line 2: `test() {
In this case, Notepad saved the file with carriage returns and linefeeds, causing the error shown above. The \r indicates a carriage return (Linux systems terminate lines with linefeeds \n only).
On the linux machine, you could test this theory by running the following to strip carriage returns from the file, if they are present:
cat originalfile | tr -d "\r" > newfile
Then try to run the new file sh ./newfile . If this works, the issue was carriage returns as hidden characters.
Note: This is not an exact replication of your environment (I don't have access to a Mac), however it seems likely to me that the issue is that an editor, somewhere, saved carriage returns into the file.
--- /EDIT
To elaborate a little, operating systems and editors can have different file encoding defaults. Typically, applications and editors will influence the filetype encoding used, for instance, I think Microsoft Notepad and Notepad++ default to Windows-1252. There may be newline differences to consider too (In Windows environments, a carriage return and linefeed is often used to terminate lines in files, whilst in Linux and OSX, only a Linefeed is usually used).
A similar question and answer that references file encoding is here: bad character showing up in bash script execution
try something like
$ sudo apt-get install dos2unix
$ dos2unix offendingfile
Easy way to convert example.sh file to UNIX if you are working in Windows is to use NotePad++ (Edit>EOL Conversion>UNIX/OSX Format)
You can also set the default EOL in notepad++ (Settings>Preferences>New Document/Default Directory>select Unix/OSX under the Format box)
Thanks #jdt for your answer.
Following that, and since I keep having this issue with carriage return, I wrote that small script. Only run carriage_return and you'll be prompted for the file to "clean".
https://gist.github.com/kartonnade/44e9842ed15cf21a3700
alias carriage_return=remove_carriage_return
remove_carriage_return(){
# cygwin throws error like :
# syntax error near unexpected token `$'{\r''
# due to carriage return
# this function runs the following
# cat originalfile | tr -d "\r" > newfile
read -p "File to clean ? "
file_to_clean=$REPLY
temp_file_to_clean=$file_to_clean'_'
# file to clean => temporary clean file
remove_carriage_return_one='cat '$file_to_clean' | tr -d "\r" > '
remove_carriage_return_one=$remove_carriage_return_one$temp_file_to_clean
# temporary clean file => new clean file
remove_carriage_return_two='cat '$temp_file_to_clean' | tr -d "\r" > '
remove_carriage_return_two=$remove_carriage_return_two$file_to_clean
eval $remove_carriage_return_one
eval $remove_carriage_return_two
# remove temporary clean file
eval 'rm '$temp_file_to_clean
}
I want to add to the answer above is how to check if it is carriage return issue in Unix like environment (I tested in MacOS)
1) Using cat
cat -e my_file_name
If you see the lines ended with ^M$, then yes, it is the carriage return issue.
2) Find first line with carriage return character
grep -r $'\r' Grader.sh | head -1
3) Using vim
vim my_file_name
Then in vim, type
:set ff
If you see fileformat=dos, then the file is from a dos environment which contains a carriage return.
After finding out, you can use the above mentioned methods by other people to correct your file.
I had the same problem when i was working with armbian linux and Windows .
i was trying to coppy my codes from windows to armbian and when i run it this Error Pops Up. My problem Solved this way :
1- try to Coppy your files from windows using WinSCP .
2- make sure that your file name does not have () characters

Can't read to var in Bash

I wrote a little Bash script and I'm having a problem while reading from the command line. I think its because I wrote the script on Windows. Here is the code:
read NEW_MODX_PROJECT
and the output of the debug mode
+ read $'NEW_MODX_PROJECT\r'
Finally here the error I get
': Ist kein gültiger Bezeichner.DX_PROJECT
I think in English it should mean "': is not a valid identifier.DX_PROJECT"
While writing it on Windows, it worked fine. I used console2 to test it which is using the sh.exe.
Your assertion is correct -- Windows uses CRLF line separators but Linux just uses a LF.
The reason for your strange error message is that while printing the name of your variable, it includes the carriage return as part of its name -- the terminal then jumps back to the first column to print the rest of the error message (which overwrites the beginning of the message with the end of it).
There are a set of utilities known as dos2unix and unix2dos which you can use to easily convert between formats, e.g.:
dos2unix myscript.sh
If you don't happen to have them, you can achieve the same using tr:
tr -d '\r' < myscript.sh > myscript-new.sh
Either will strip all the carriage returns and should un-confuse things.

Resources