This question already has answers here:
'\r': command not found - .bashrc / .bash_profile [duplicate]
(17 answers)
Closed 5 years ago.
echo "Select your option:"
echo "1. Change ip address"
echo "2. Add route"
echo "3. Reboot"
echo "4. Exit"
read A
case $A in
1)
echo "Add Ip address"
read IP
echo "Add Netmask"
read Netid
echo "Add name of interface"
read Interface
ifconfig ${Interface} ${IP}/${Netid}
if [ $? -ne 0 ];then
echo "Ip address not configured"
fi
;;
2)
echo "Add Destination"
read dst
echo "Add Netmask"
read Netid
echo "Add Gateway"
read gw
route add $dst mask $Netid gw $gw
if [ $? -ne 0 ];then
echo "Route not added"
fi
;;
3)
reboot
;;
4)
echo "Bye"
exit 0
;;
default)
echo "Wrong selection"
exit 1
esac
Error:
[b104#b104 Downloads]$ ./NetworkUtility.sh
./NetworkUtility.sh: line 1: $'\r': command not found
Select your option:
1. Change ip address
2. Add route
3. Reboot
4. Exit
1
': not a valid identifier 7: read: `A
./NetworkUtility.sh: line 8: $'\r': command not found
./NetworkUtility.sh: line 9: syntax error near unexpected token `newline'
'/NetworkUtility.sh: line 9: `case $A in
[b104#b104 Downloads]$
It seems that you have Windows style line endings (\r\n) - you need to change them to unix style (\n). If you have dos2unix installed you could use it. You could also do it using sed or awk.
Its End of Line(EOL) conversion issue when script is written in windows using some editors like notepad, notepad++(tested).
Sed , tr may solve the issue in case of you just need to run script, however if you are developing shell script its become annoying each time first convert using, sed/tr command then run your script.
Notepad++ has an option to convert END OF LINE CONVERSION(EOL).
How to do that:
go to Edit > EOL Conversion > select Unix/OSX
Here you go, save script file and run it.
Here is screenshot of the same
The error happens, because shell doesn't understand DOS/Windows-like line endings and it expects LF instead of CRLF.
You'll need to first configure your editor to use Unix-like line endings or use dos2unix command to change it automatically, e.g.
dos2unix ./NetworkUtility.sh
Read more details at: '\r': command not found.
If you're using Vagrant, check: Windows CRLF to Unix LF Issues in Vagrant
Related
This question already has answers here:
Why should there be spaces around '[' and ']' in Bash?
(5 answers)
Closed 6 years ago.
I have a bash script to set the keyboard type of my external and internal laptop keyboards (so as they are both usable and output the correct characters).
The main part of the script works fine, but I have a problem with the switch / case for capturing the command line options.
this is the full script
#!/bin/bash
###functions first
usage()
{
echo "script to set the internal and external keyboards to french and english repectively"
}
setKeyBoardMap()
{
echo "setting dual keyboard."
echo "setting keyboard types..."
setxkbmap -device 13 fr
setxkbmap -device 10 gb
echo "done"
}
##the main show
#capture command line parameters
if ["$1" = ""]; then
#no command line parameters
setKeyBoardMap
exit 0
else
while [ "$1" != " "]; do
case $1 in
-h | --help) usage
exit 1
;;
-*|--*)
echo "Unknown option $1"
echo "please use -h or --help for usage details"
exit 1
;;
#add any switches in here
#you may decide to modify this to set the keyboard
#according to your prefered type.
esac
done
fi
When I call this from my home directory I get the following
:~$ bash -x 2Keyb.sh -h
+ '[-h' = ']'
2Keyb.sh: line 31: [-h: command not found
+ '[' -h '!=' ' ]'
2Keyb.sh: line 37: [: missing `]'
I'm not sure what I'm missing but I'm sure it is in my while statement.
I know that having this construct for command line arguments is a bit excessive, but I plan to make this usable on any laptop to set the keybaord language between any 2.
But first I need to get it working as it.
If I don't pass any arguments the script functions perfectly...
Thanks in advance, your help is appreciated.
David
while [ "$1" != " "]; do
^^ space missing here
Also as mentioned by Codegnome there is shellcheck, a static analyzer for shell scripts. I personally use the shellcheck binary in combination with vim and the syntastic plugin -> very useful to find this kind of errors.
I'm new to scripting.
I downloaded cygwin and Notepad++(I'm using unix option-for writing and saving the ".sh files")
I have below script
Below code is from command $ cat -v pinging.sh
#!/bin/bash
target=$1
# email report when
SUBJECT="Ping failed"
EMAILID="someemailid#gmail.com"
count=$( $SYSTEMROOT/system32/ping -n -c 1 $target | grep 'received')
if [ $count == 0 ];
then
echo "Host : $target is not Alive!! Try again later.. at $(date)" | mail -s "$SUBJECT" $EMAILID
else
echo "Yes! Host is Alive!"
fi
done
But my script is giving error -
$ ./pinging.sh www.google.com
./pinging.sh: line 9: [: ==: unary operator expected
Yes! Host is Alive!
./pinging.sh: line 17: syntax error near unexpected token `done'
./pinging.sh: line 17: `done'
I'm not sure what I am doing wrong here.
The script is giving error
I'm getting- "host is alive" message always even in case of destination unreachable messages too. If I'm using ping www.somesite.com and if I'm getting destination unreachable through cygwin or cmd, this code is giving host is alive.
I also tried if [ $count -et 0 ]; in above code
Please help me!
Best Regards,
The value of the $count variable is not a number. It is a full line of text.
When you expand it in the [ test (without quotes) it gets word-split by the shell and the contents of the [ test become invalid (too many words) and you get your error.
If you quote "$count" you will avoid the error (but still not get the results you want).
You need to filter out only the number from the ping output and then use that in your [ test.
Add set -x to the top of your script to see the commands that are actually being run and you'll see the problem.
I am new to bash and trying to write a script that disables kworker business as in aMaia's answer here.
So far, I have this, which I run from root:
1 #!/bin/bash
2
3 cd /sys/firmware/acpi/interrupts
4 for i in gpe[[:digit:]]* # Don't mess with gpe_all
5 do
6 num=`awk '{print $1}' $i`
7 if (( $num >= 1000 )); then # potential CPU hogs?
8 # Back it up and then disable it!!
9 cp $i /root/${i}.backup
10 echo "disable" > $i
11 fi
12 done
But running it results in:
./kkiller: line 10: echo: write error: Invalid argument
What is going on here? I thought $i was just the file name, which seems like the correct syntax for echo.
Suggestions for cleaning up/improving the script in general are also appreciated!
Update: With set -vx added to the top of the script, here is a problematic iteration:
+ for i in 'gpe[[:digit:]]*'
awk '{print $1}' $i
++ awk '{print $1}' gpe66
+ num=1024908
+ (( 1024908 >= 1000 ))
+ cp gpe66 /root/gpe66.backup
+ echo disable
./kkiller: line 10: echo: write error: Invalid argument
I had this problem too in Docker on Alpine linux environment. I think the problem is that echo by default put a newline character at the end of the string, and the kernel not accept it, but it is not the case in every system. In Docker I had this error, but the value was written despite the error message.
The solution (in Bash): echo -n disable >/sys/firmware/acpi/interrupts/gpe66. This way no newline is echoed.
Double-check all spelling. echo "disabled" will emit a write error even for root whereas echo "disable" succeeds.
I think it has something to with permissions. I don't think root has write access to those files by default. Try echoing manually 'disable' to that file, even as root you get the same error shown. So to make your script work, first do chmod 744 on $i before your echo, it should do the trick.
I got the same error message trying to disable a GPE that was already set to disabled:
# echo "disable" > /sys/firmware/acpi/interrupts/gpe17
-su: echo: write error: Invalid argument
# cat /sys/firmware/acpi/interrupts/gpe17
3718289 STS disabled unmasked
After enabling it, I could disable it without an error:
# echo "enable" > /sys/firmware/acpi/interrupts/gpe17
# echo "disable" > /sys/firmware/acpi/interrupts/gpe17
#
I am tring to understand how to use the diff command to undersand the difference between these files. Can someone please explain what this means? cases.sh was written in notepad++, cases2.sh was written in nano from within cygwin on windows7. but I cannot see the difference as I don't think it is visible? what is the advice for getting cases.sh to work, but I want to understand what is wrong with it.
$ diff cases.sh cases2.sh
1,13c1,13
< #!/bin/sh
< # Prompt user to enter a character
< echo "Please enter a letter:"
< read charac
< case $charac in
< "a"|"A") echo "You have typed a vowel!" ;;
< "e"|"E") echo "You have typed a vowel!" ;;
< "i"|"I") echo "You have typed a vowel!" ;;
< "o"|"O") echo "You have typed a vowel!" ;;
< "u"|"U") echo "You have typed a vowel!" ;;
< *) echo "You have typed a consonant!" ;;
< esac
< exit 0
\ No newline at end of file
---
> #!/bin/sh
> # Prompt user to enter a character
> echo "Please enter a letter:"
> read charac
> case $charac in
> "a"|"A") echo "You have typed a vowel!" ;;
> "e"|"E") echo "You have typed a vowel!" ;;
> "i"|"I") echo "You have typed a vowel!" ;;
> "o"|"O") echo "You have typed a vowel!" ;;
> "u"|"U") echo "You have typed a vowel!" ;;
> *) echo "You have typed a consonant!" ;;
> esac
> exit 0
cases.sh does not work, I wrote this in notepad++ and I get the error below
$ ./cases.sh
Please enter a letter:
t
': not a valid identifier `charac
./cases.sh: line 5: syntax error near unexpected token `$'in\r''
'/cases.sh: line 5: `case $charac in
cases2.sh does work but I wrote this in nano from within cygwin on windows7
$ ./cases2.sh
Please enter a letter:
t
You have typed a consonant!
try turning on "show all characters" in notepad++ ... sounds like you have windows-style newlines set for your default editor settings there. Convert the file to unix-style newlines and try running it.
You're encountering the classic linefeed problem.
Linux and the Unices (including compatibility layers like Cygwin) use a single \n (newline) to terminate each line, while the Windows family uses \r\n (carriage return, newline) for each line.
As a result, many (although not all) Unix utilities will choke on scripts written on Windows, as they contain additional, invisible, carriage returns. In your case, diff knows that cases1.sh differs from cases2.sh on those lines, but doesn't display the \r characters that actually cause the difference. Similarly, bash gets caught up on the carriage returns.
The easiest solution is enable Unix line endings in your editor of choice, and to run a tool like dos2unix on the scripts you've already written. It should be available in Cygwin's repositories.
What is wrong with the 5th line in this script ( I have included the snippet that gives me the error and the actual error is listed in the bottom after the code and a link to complete script)?
#! /bin/bash
INSTALLDIR=/usr/local/mapguideopensource
CLEAN_FLAG=0
while [ $# -gt 0 ]; do # Until you run out of parameters...
case "$1" in
-prefix|--prefix)
INSTALLDIR="$2"
shift
;;
-clean|--clean)
CLEAN_FLAG=1
shift
;;
-help|--help)
echo "Usage: $0 (options)"
echo "Options:"
echo " --prefix [installation directory]"
echo " --clean [clean all objects and binaries in Oem]"
echo " --help [Display usage]"
exit
;;
esac
shift # Check next set of parameters.
done
This is the error i get when i run this bash script on linux (REHL5) :
: command not founde 4:
: command not founde 8:
: command not founde 8:
: command not founde 12:
MapGuide Open Source build script for OEM components
'/build_oem.sh: line 17: syntax error near unexpected token `in
'/build_oem.sh: line 17: ` case "$1" in
Please note, that the line number above corresponds to the actual script i am running (i have included a link to that script below)
The original script i am running
From the errors, I'm pretty sure you have carriage returns (aka CR or ^M) at the end of the lines. Windows/DOS text files have carriage return AND linefeed at the end of each line, but unix programs (like bash) just expect a linefeed, and get horribly confused if there's a CR as well. The giveaway is error messages like:
: command not founde 4:
What this really is is ./build_oem.sh: line 4: ^M: command not found, but the carriage return makes the terminal go back to the beginning of the line, and write the end of the message over the beginning of the message:
./build_oem.sh: line 4:
: command not found
|
V
: command not founde 4:
To fix the script, use dos2unix to convert it to proper unix format, then switch to a text editor that saves in unix format.
What choroba says, but also note that your shebang has to be on the first line (which it is not), otherwise it is useless since it's just a plain comment then and it won't necessarily execute under bash.
In the original script, lines 4 and 8 are empty. There is probably some invisible control character on the lines. Try xxd build_oem.sh.