issue with array in shell on ubuntu - arrays

I used to have a server running CentOS, and I used to execute shell files this way:
sudo sh /folder/script.sh
Now I have an Ubuntu server. When I'm executing the same command line, I now have the following error message:
/folder/script.sh: ID[0]=ID: not found
I had a look on the internet and it says I need to use:
sudo /bin/bash /folder/script.sh
But when I do so I got the same error message.
The first line of my script is:
ID[0]="ID"

/bin/sh is often a POSIX shell, which does not support arrays.
I suggest you install another shell which does support them, like mksh (disclaimer: I’m its developer), ksh93, zsh, or just use GNU bash instead, and call your script with, for example, sudo mksh /folder/script.sh instead. This will give you more consistent behaviour across systems, too (note that to behave consistent on all platforms is actually an mksh design goal).
Hm… this works for me:
$ cat >x
#!/bin/bash
ID[0]="ID"
echo works for me
$ mksh x
works for me
Do you have any weird characters in your script, like embedded Carriage Return (^M)? Check with: cat -v /folder/script.sh

Related

Detect ksh array support in shell script

Is it possible to write a /bin/sh shell script that detects whether or not the underlying shell supports ksh-style arrays? The latter are supported at least in ksh and bash, and in zsh with an option.
Since sh does not allow arrays, and there is no concept of a underlying shell.
Of course it is possible that on your platform, /bin/sh is symlinked to some other shell, or (as it happens on my symstem) is a copy some other shell (i.e. someone has performed a, say, cp /bin/bash /bin/sh).
To test for a symlink, you could do a ls -l /bin/sh and investigate its output.
To test for equality, the best you could do is to loop through the candidate shells you are considering, and test for equality. For instance:
for s in bash ksh
do
if cmp -s /bin/sh /bin/$s
then
echo /bin/sh is in reality a $s
break
fi
done
Of course there is no guaranteed way that it works.
Another possibility would be to run (perhaps using eval) some code fragments which use bash arrays, respectively ksh arrays, and analyze the stderr of it to detect, which ones gives syntax errors.

Error in creating array variable in Debian 8.4

I have a very basic shell script containing
#!/bin/sh
NAME[0]="Hello"
echo ${NAME[0]}
So when I run this script an error occurs stating
./test.sh: 2: ./test.sh: NAME[0]=Hello: not found
./test.sh: 3: ./test.sh: Bad substitution
So basically I looked through a few tutorials and found this to be the basic way to declare arrays. So I am confused as to why this is an error. Any ideas?
You are starting your script as #!/bin/sh, which has a soft link to dash (The current version of sh which conforms with the POSIX 1003.2 and 1003.2a specifications for the shell) and dash doesn't support arrays. In debian 8 onwards dash has become default shell, so if you run ls -la /bin/sh the output will be /bin/sh -> dash
However bash still remains the default login shell, only the default /bin/sh used in shell scripts has been changed. So if you run your code on terminal, it will work just fine. More information on why this switch was made in Ubuntu can be found here.
If you want to use arrays in your script then you must start your script with #!/bin/bash
So your script works perfectly if modified like this
#!/bin/bash
NAME[0]="Hello"
echo ${NAME[0]}
More information on Dash as Sh DashAsBinSh

Use of su command in c code

I want to use a command in my c code. This command works properly when i am a superuser in terminal (using su) but does not work when I use sudo. I gathered that I can use system() in my c code as follows
system("su -c \"mycommand\"")
myCommand is a command that sends input to some device, like (echo 1 > mydevice)
I compiled my c code using gcc and run the output file. The trouble is, it wants root password from terminal when it comes to this line.
Is there a way I supply password programatically? I did it before with sudo command with -S option, but sudo command does not work for this case. If it is not possible, is there another way to deal with this?
Try this instead,
system("sudo sh -c \"mycommand\"");

I am getting error "array.sh: 3: array.sh: Syntax error: "(" unexpected"

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.

Bash Loop 2 Arrays

I'm trying to create a loop for a couple of arrays but I get this error:
./bash.sh: 3: ./bash.sh: source[0]=/media/jon/my\ directory/: not found
This is what my code looks like:
sourceFiles[1]=/media/jon/ACER/Documents\ and\ Settings/Laura/Documents/Shared
destinationFiles[1]=/media/jon/My\ Book/Shared
for index in ${!sourceFiles[#]}
do
sudo rsync -a --delete ${sourceFiles[$index]} ${destinationFiles[$index]}
done
I'm some what green to bash files and this is terribly frustrating that doing a simple loop is so difficult.
Update
I needed a #!/bin/bash at the top per the correct answer.
Your code looks ok. I think you're not using bash though ("not found" is not a bash error message). Are you perhaps using /bin/sh? On many systems that's a minimal POSIX shell, not bash.
A POSIX shell would not recognize sourceFiles[1]=... as an assignment and would consequently run it as a command. Hence the "not found" error.
Try enclosing in double quote your variables in your sudo line:
sudo rsync -a --delete "${sourceFiles[$index]}" "${destinationFiles[$index]}"

Resources