The Linux script does not run on MacOS - bash

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.

Related

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.

Is setsid command missing on OS X?

I mean I can't use it in bash, is it not available on OS X, or is it just missing on my Mac?
It's not a PATH variable issue, because I searched with find command, and there's no file named setsid on my Mac at all.
If it's missing on OS X, is there any alternative to it?
Or if it's the case that I somehow deleted it accidentally, where can I find a copy of it?
use Brew:
brew install util-linux
Yes. /usr/bin/setsid is missing on Mac OS/X.
The OS interface is available, so based on the chapter 2 man page there may be some hope for porting the Linux source to Darwin.
While macOS does not come with a setsid command, it does come with scripting languages which support calling the setsid C function, such as Perl and Python. So, if you don't want to (or for some reason can't) install a setsid command via Homebrew (or MacPorts or whatever), another option is to write your own in a scripting language. As an example, try this Perl script (which I based off this with some minor changes):
#!/usr/bin/perl -w
use strict;
use POSIX qw(setsid);
fork() && exit(0);
setsid() or die "setsid failed: $!";
exec #ARGV;
If you don't like Perl, Python's os module has a setsid function too.
A simple demo, which relies on the fact that /dev/tty is an alias of your controlling terminal if you have one, but reads/writes to it fail with an IO error if you don't:
$ bash -c 'echo I have a controlling terminal. > /dev/tty'
I have a controlling terminal.
$ ./setsid.pl bash -c 'echo I have a controlling terminal. > /dev/tty'
bash: /dev/tty: Device not configured
$
(Warning: With the release of macOS Catalina (10.15) in 2019, Apple deprecated the Perl, Python, Ruby and Tcl language runtimes shipped with macOS – they say new software should not use them, and they may be removed in a future macOS version – and Apple is not going to update their versions, which are becoming increasingly outdated. However, they are still there in Monterey, and while I haven't upgraded to Ventura yet, I haven't heard anything about their removal in that version either. One obviously shouldn't rely on them for any supported applications – if such software needs one of these runtimes, it should install its own copy of them. However, if it is just for a quick hacky script to easily test how some program behaves without a controlling terminal, using these OS-bundled runtimes is still fine.)

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

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

how to run bash file in win-bash

I am unfortunately having to use windows in work, and so I have installed win-bash to have a unix shell running. all going well but I am having an issue running the following .sh file:
bash $ ./qf.sh
.\qf.sh: option not available on this NT BASH release
.\qf.sh: fork: Bad file descriptor
qf.sh is:
#!/bin/bash
cat test.csv | while read line
do
echo "${line//,/ }" | xargs ./adder
done
I find it hard to believe someone would create a bash emulator incapable of running a bash file. curious that the error message writes .\qf as opposed to ./qf
Can anyone shed some light on this?
use MinGW or Cygwin
MinGW: http://sourceforge.net/projects/mingw/files/?source=navbar
Cygwin: http://www.cygwin.com/
Using Cygwin absolutely killed this error for me. I do wonder however, how this should work with MinGW. I don't see any unix command executable directory to include in the path (like cygwin64\bin with Cygwin)

Resources