I try to build the optiboot bootloader. This working with a few errors and I try to solve them. I guess optiboot is made to build on linux system.
So I installed https://sourceforge.net/projects/win-bash/files/shell-complete/latest/ and add its path to PATH variable.
But the bash/sh script was still comming back with "bad substitution"
The generated bash script look like the following. I added already the first line with #!/bin/bash but it gave not success.
#!/bin/bash
# 1 "baudcheck.c"
# 1 "C:\\Users\\trivalik\\Downloads\\arduino-1.8.0 \\hardware\\anet\\avr\\bootloaders\\atmega//"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "baudcheck.c"
# 24 "baudcheck.c"
bpsx=115200
bps=${bpsx/L/}
bps=${bps/U/}
fcpux=16000000L
fcpu=${fcpux/L/}
fcpu=${fcpu/U/}
echo $bpsx
echo $bps
when I execute this on operating system Windows 10 with "bash baudcheck.tmp.sh" I get:
115200
baudcheck.tmp.sh: ${bpsx/L/}: bad substitution
baudcheck.tmp.sh: ${bps/U/}: bad substitution
baudcheck.tmp.sh: ${fcpux/L/}: bad substitution
baudcheck.tmp.sh: ${fcpu/U/}: bad substitution
The main question is, what is on parameter substitiution on Windows different?
Or is it complete disabled?
All the bash tips here could me not help.
Edit:
Solution seems to be that the bash from win-bash is very very old.
The Version returns:
bash$ echo $BASH_VERSION
win-bash_0.8.5(0)
Instead I used now the bash from git for Windows https://git-for-windows.github.io/
this bash version is not the newest but higher:
$ echo $BASH_VERSION
4.3.42(5)-release
Does anybody know a higher bash Version for Windows?
Related
Is there a way to make bash warn if a variable is undefined but prevent script execution from aborting?
I'm looking for something similar to set -u, except that set -u aborts execution and I would like the script to warn, but continue execution when it finds undefined variables.
I know I can check whether a variable is set , but my scripts have hundred of variables and I'm looking for a solution that avoids checking variables one by one.
You can do it like this:
$ cat /tmp/q.sh
#!/bin/bash
set -u
echo 1
echo $2
echo 3
$ bash --norc --noprofile --noediting -i /tmp/q.sh
1
bash: $2: unbound variable
3
That is, force interactive mode (-i) when running the script, which prevents bash from aborting with set -u, but you have to also use --norc --noprofile --noediting (maybe some things more?), to make it behave more like a non-interactive shell.
I can't tell if this is expected or unexpected behavior, though (it doesn't work when using -c). Works on versions 4.2.46(2)-release (Oracle Linux 7), 4.1.2(1)-release (Oracle Linux 6) and 5.1.16(1)-release (Arch Linux).
I have written the following code:
#!/bin/bash
#Simple array
array=(1 2 3 4 5)
echo ${array[*]}
And I am getting error:
array.sh: 3: array.sh: Syntax error: "(" unexpected
From what I came to know from Google, that this might be due to the fact that Ubuntu is now not taking "#!/bin/bash" by default... but then again I added the line but the error is still coming.
Also I have tried by executing bash array.sh but no luck! It prints blank.
My Ubuntu version is: Ubuntu 14.04
Given that script:
#!/bin/bash
#Simple array
array=(1 2 3 4 5)
echo ${array[*]}
and assuming:
It's in a file in your current directory named array.sh;
You've done chmod +x array.sh;
You have a sufficiently new version of bash installed in /bin/bash (you report that you have 4.3.8, which is certainly new enough); and
You execute it correctly
then that should work without any problem.
If you execute the script by typing
./array.sh
the system will pay attention to the #!/bin/bash line and execute the script using /bin/bash.
If you execute it by typing something like:
sh ./array.sh
then it will execute it using /bin/sh. On Ubuntu, /bin/sh is typically a symbolic link to /bin/dash, a Bourne-like shell that doesn't support arrays. That will give you exactly the error message that you report.
The shell used to execute a script is not affected by which shell you're currently using or by which shell is configured as your login shell in /etc/passwd or equivalent (unless you use the source or . command).
In your own answer, you say you fixed the problem by using chsh to change your default login shell to /bin/bash. That by itself should not have any effect. (And /bin/bash is the default login shell on Ubuntu anyway; had you changed it to something else previously?)
What must have happened is that you changed the command you use from sh ./array.sh to ./array.sh without realizing it.
Try running sh ./array.sh and see if you get the same error.
Instead of using sh to run the script,
try the following command:
bash ./array.sh
I solved the problem miraculously. In order to solve the issue, I found a link where it was described to be gone by using the following code. After executing them, the issue got resolved.
chsh -s /bin/bash adhikarisubir
grep ^adhikarisubir /etc/passwd
FYI, "adhikarisubir" is my username.
After executing these commands, bash array.sh produced the desired result.
I have the following logic in the script Setup.sh.
#!/bin/bash
for ((i = 0 ; i < 5 ; i++))
do
echo "Welcome $i times."
done
When I run the script using the command ./Setup.sh, I get the error
./Setup.sh: line 3: syntax error near unexpected token `(('
./Setup.sh: line 3: `for ((i = 0 ; i < 5 ; i++))'
When I run the script using the command sh Setup.sh , I get the error
Setup.sh: syntax error at line 3: `(' unexpected
When I run the script logic in Execute BASH Shell Script Online using http://www.compileonline.com/execute_bash_online.php, it executes perfectly and prints the following.
Welcome 0 times.
Welcome 1 times.
Welcome 2 times.
Welcome 3 times.
Welcome 4 times.
Can someone help me understand why I get this error on Sun Solaris Unix machine?
When you run sh Setup.sh the Solaris /bin/sh is used to execute the script. The Solaris /bin/sh is not a POSIX shell and also does not understand the non-portable (()) syntax.
If you use #!/bin/bash it should work. If it doesn't, maybe your bash is very ancient. What does bash --version output?
The online demo uses bash 4.1.2(1)-release.
Please check which version of bash you have on the Solaris system.
bash --version
As far as I remember, the (( )) arithmetic notation was introduced recently. And it's a bashism, so it does not work with sh.
The website probably uses a new version of bash.
I'm trying to learn how to write portable shell scripts, to do so I'm starting to migrating my personal utilities from bash to sh (dash on my system). There is however a error I'm getting in all cases when I try to run the scripts in debugging mode $ dash -x script
For instance, on this script:
#!/bin/sh
echo hi
If I run it as: $ dash script, I get the 'hi' string, however if I run it as: $ dash -x script or if I add the set -x command before echo:
#!/bin/sh
set -x
echo hi
It fails with the error:
script.sh: 3: script.sh: Bad substitution
this makes very difficult to debug my scripts. I'm running ubuntu 12.04 with dash 0.5.7-2ubuntu2
Just by the time I finished writing my question I realized I was using a personalized PS4 (which is used in xtrace mode), my PS4 was defined as:
>>(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }
I changed temporarily as PS4=">>" and everything went ok, I can now debug my scripts on dash. Hope this helps someone.
Consider this (exemplary) bash script:
#!/bin/bash -e
errorExit() {
echo "" >&2
echo "ERROR (${var_scriptfilename}):" >&2
echo "An unhandled error occurred." >&2
intentionalExit 1
}
intentionalExit () {
trap - EXIT # Unregister the EXIT trap
exit $1
}
trap errorExit EXIT # Trap script errors
var_scriptfilename="$(basename "$0")"
# ==== START OF TEST ====
var_counter=0
((var_counter++))
echo "var_counter is $var_counter" >&2
# ===== END OF TEST =====
intentionalExit 0
If I run it in Cygwin's bash it produces the intended output:
var_counter is 1
However, if I run it on my Debian Squeeze box, which is its intended destination, I end up in the EXIT trap:
ERROR (test.increment.sh):
An unhandled error occurred.
...Why is that?
If I remove the -e option it works as expected on both systems, but I want to keep -e in use, obviously.
The slightly more cumbersome "universal" variant, var_counter=$(($var_counter+1)), works with -e being set on both shells, but I would prefer to use the first notation (or something similar-looking) since it clearly sticks out as an increment operation when reading the code.
bash --version on the Cygwin bash says:
GNU bash, version 3.2.51(24)-release (i686-pc-cygwin)
Copyright (C) 2007 Free Software Foundation, Inc.
On Debian, it is:
GNU bash, Version 4.1.5(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
I am intrigued as to why this is that way. Does anybody know the cause of this behavior?
Also, does anybody know of a similar-looking way to increment a variable in bash that I could use?
From the bash4 manpage on Debian:
((expression))
The expression is evaluated according to the rules described
below under ARITHMETIC EVALUATION. If the value of the expresâ
sion is non-zero, the return status is 0; otherwise the return
status is 1. This is exactly equivalent to let "expression".
and also ...
-e Exit immediately if a pipeline (which may consist of a
single simple command), a subshell command enclosed in
parentheses, or one of the commands executed as part of
a command list enclosed by braces (see SHELL GRAMMAR
above) exits with a non-zero status.
So what is happening is ((var++)) increments var from 0 to 1 and returns
0, causing the overall expression to return non-zero, which triggers
errexit.
Now for the difference between the two different bash versions: this change
in (( behavior seems to have occurred between 4.0 and 4.1. In 4.0 ((
apparently did not trigger errexit. See this NEWS file for the details.
You'll have to scroll down to line 135 or so. The Changelog from the source
distribution seems to confirm this.
If you just want a variable incremented without using the exit status,
there's multiple ways to do it. Maybe some other people could give advice
on which is the best, but some possibilities are:
var="$((var+1))", the portable POSIX sh method
((var++)) || true, forcing the statement to always have a zero
exit status (bash only)