why doesn't echo test &>>file work on OS X - macos

I have some scripts that I made on an ubuntu box, but these won't work on my OS X.
echo test &>>file
-bash: syntax error near unexpected token `>'
The idea is that I want to take both stdout and stderr and put into a file.

The redirection operator &>> appears in Bash version 4.
With Bash 3.x (which is the one shipped by default on OSX) you must use the equivalent form:
>>file 2>&1

Related

The Linux script does not run on MacOS

I have a script for work which runs fine on Ubuntu Virtual machine. I have recently switched to MacOS and while trying to run the same script I get the following error:
danyateran#MacBook-Air-Danya:~/restorator$ ./restorator.sh -V
/Users/danyateran/restorator/bin/functions.sh: line 1568: syntax error near unexpected token `>'
/Users/danyateran/restorator/bin/functions.sh: line 1568: ` ssh_conn "${SOURCE_SERVERNAME}" 'exec 2>&1; whmapi1 fetch_ssl_certificates_for_fqdns domains='${ssl_host}'; exit' &>> "${TMP_TRANSFER_DIR}/ssl_info_${ssl_host}.txt"'
While the syntax seems fine and as far as I know the MacOS has the same line endings as Linux, I have no idea what could be wrong. What is the cause of this MacOS-related problem and how can it be resolved?
The syntax &>>, which appends both standard output and standard error to the same file, was introduced in bash version 4.0. MacOS ships with bash version 3.2.
You can change it to the more portable syntax:
>> "${TMP_TRANSFER_DIR}/ssl_info_${ssl_host}.txt" 2>&1
That's same thing, but will be understood by bash v3.2 (and newer, and sh).
However, there might be other things in the script which are not compatible, such as associative arrays, the mapfile built-in, various shell options, etc.
You can install a newer version of bash. The current version is 5.1.

Failure in executing shell script producing output on Ubuntu on Windows

I have had a hard time in executing my shell scripts on bash on Ubuntu on windows 10. The script is very simple:
# file name: submission.sh
echo "Hello world" > output.txt
When I executed it with a command sh submission.sh, it gave me an error:
$ sh submission.sh
: Directory nonexistentssion.sh: cannot create output.txt
However, when I changed the script into
# file name: submission.sh
echo "Hello world"
and executed it with the same command sh submission.sh, it gave me the right output
$ sh submission.sh
Hello world
It seems like bash on Ubuntu on Windows cannot get it right when the script involves directing the output to a file. Is there any solution or workaround to this?
EDIT:
Details on my system:
Program: "Bash on Ubuntu on Windows"
OS: Windows 10 Version 1709
EDIT:
Typing the command directly on the terminal works, i.e.
$ echo "Hello world" > output.txt
$ cat output.txt
Hello world
I still wants to put the commands on a file and execute the file instead of writing the command directly to the terminal, and this is still unsolved.
You appear to have mangled text in nonexistentssion.sh: and No such file or directorytput.txt which suggests you might have Windows line-endings in the file \r. If you created the script using a Windows program (like Notepad) then that could be the case.
If you have dos2unix then run it on your script and try again.
By the way for future reference, running sh is not the same as running bash. In this case it would have made no difference, but sh is a POSIX shell, full bash has many extensions which will not work under sh.
Some platforms run sh as a symbolic link to bash which fools people into thinking they are the same, but bash detects this and switches to POSIX mode when running as sh. It is a common issue here.
In your submission.sh file, is better to add a shebang as first line.
Another thing you want to consider if you want to use sh instead of bash is to replace echo with printf, for portability
Your code should look something like:
#!/bin/bash
printf "Hello world!\n" > output.txt
You can call it simply by ./submission.sh and because of the shebang, your terminal will know how to open it [:
P.S. Keep in mind that because of the standard umask in Ubuntu, you might want to execute chmod u+x submission.sh before running it.
Also, notice that your error is probably caused by a permissions issue.
Try adding write permissions in the folder you are launching the script.

Parameter substitution bad substitution error on macOS High Sierra

The ${parameter[^|^^|,|,,][pattern]} parameter substitution is giving me a bad substitution error.
$ echo $greeting
hello world
$ echo "${greeting^}."
-bash: ${greeting^}.: bad substitution
I updated to the latest bash version and keep getting the error.
GNU bash, version 4.4.19(1)-release (x86_64-apple-darwin17.3.0)
I've looked everywhere and the only suggestion I've found is making sure it's running bash 4.
$ echo $SHELL
/bin/bash
I'm running macOS High Sierra.
Your default shell is not the bash shell (downloaded from brew install bash) that contains the v4 which supports the parameter expansion syntax you are referring to.
On macOS echo $BASH_VERSION will tell you the version of the current shell. bash --version tells you the version of the first bash in your $PATH. So the way you were looking at the version was not telling you the version that you were running.
You need to add the recent version of bash to the file /etc/shells as the last line and use the command to set the shell as the default on Terminal
chsh -s /usr/local/bin/bash "$USER"
After this close and re-open the Terminal to make it effect. Without adding this default option in your Terminal, you could only use the recent bash only on scripts with interpreter she-bang set to #!/usr/local/bin/bash
See also this Ask Different answer to - Update bash to version 4.0 on OSX

Why can't I execute a shell script using . ./test.sh?

I have a simple shell script:
#!/bin/bash
echo test
I can execute script successfully as:
./test.sh
and
source ./test.sh
However, the following throws an error:
. ./test.sh
error:
.: Command not found.
What could be causing the error? This works on el capitan (which was an upgrade) but not on sierra. Did something change with the terminal or default shell in the past few major releases?
I'm running macOS 10.12.3 with the default terminal - this is a clean install and NOT an upgrade (upgrades hang onto previous shell settings).
It sounds like you've switched your default shell to something other than bash, probably csh, where (a) . is not built-in command (only source is), and (b) even if it were, you couldn't load Bash code into the current session anyway.
To check what your default shell is, run echo $SHELL.
Run chsh -s /bin/bash to switch back to bash as your default shell.

How do I execute a .lua file in CygWin?

I have just installed CygWin and curl because I wanted to do something unrelated. But now, I want to execute a .lua file in CygWin and I want the results to print on the current window, the CygWin window. I want it to be like the equivalent of just opening CMD and then do cd <directory where the file is>. And then just do <filename>.lua and it prints the results. So how would I go about doing that? Sorry, I'm kinda new to Linux, Unix, CLI, ect., and I don't know much about the bash command.
I tried using the method from here: How do I execute a file in Cygwin?
I just did ./<filename>.lua and I get
./<filename>.lua: line 1: syntax error near unexpected token `"Hello world"'
./<filename>.lua: line 1: `print("Hello world")'
The file just has
print("hello world")
If your file is marked as an executable, running ./<filename>.lua will default to executing the file as a shell script, (i.e., sh, bash, zsh, etc.). This results in the error you see, which is easily recreated.
In bash:
$ echo 'print("Hello world")' > script.sh && chmod +x script.sh && ./script.sh
./script.sh: line 1: syntax error near unexpected token `"Hello world"'
./script.sh: line 1: `print("Hello world")'
The first thing you need to do is make sure Lua is installed (rerun the Cygwin setup GUI, or use a tool like apt-cyg), and is located in your $PATH.
Then instead of executing the file directly, run it with the Lua interpreter.
$ lua <filename>.lua
Alternatively, use a shebang directive to instruct the shell on how the file should be executed.

Resources