Any recommended resources for shell scripting on macs? - macos

Somebody wants me to shell script something for his Mac. I don't even script on my Linux, and I'm not even sure what shell to expect on a Mac. What are some good resources for starting Mac shell scripting? Or any viable alternatives you can think of - as long as it doesn't require 3rd party software.

http://developer.apple.com/internet/opensource/opensourcescripting.html

The shells on the Mac are the same ones you'd find on Linux; bash, tcsh, ksh, and zsh are installed by default.

Related

Why & How fish does not support POSIX?

I have heard about fish that it's a friendly and out-of-box shell but also it doesn't support POSIX standard.
On the other hand I read about POSIX standard (and also I tested it on my Fedora, It's amazing and out-of-box shell now I want to change my default shell to fish).
But the matter that I opened this question for is: I misunderstood about relation between fish and POSIX standard, what do you mean about fish does NOT support POSIX exactly? & How? (Should I change my bash to fish?).
Please explain it simple 'cause I'm a little newbie, thanks.
fish isn't and never tried to be compatible with POSIX sh.
This really just means that it's a separate language (like Java, Python or Ruby) rather than an implementation or extension of sh (like Bash, Dash and Ksh).
Obviously, just like you can't copy-paste Java snippets into a Python program, you can't copy-paste sh code into fish.
In practice, this means that when you search for things like "how do I show the current git branch in my prompt", you need to make sure you find fish answers because the sh ones won't work. Similarly, when books or instructions give commands to run, you may occasionally need to rewrite some of them manually (or open a bash shell and paste them there).
Whether this matters is entirely up to you, so definitely give it a go.
Actually, fish is not compliant with the POSIX sh definition. But neither is csh (and probably zsh). You still can use fish as your interactive shell.
For example echo $$ shows the pid of the shell in POSIX sh. But with fish it does not.
(and that is why I did not switch to fish and keep using zsh as my daily interactive login shell)
You could change your interactive login shell (using chsh) to fish.
But if you write shell scripts, writing them for the POSIX sh specification make these scripts more portable. (You'll use the shebang #!/bin/sh to start them, it is understood by Linux execve(2)). In some cases, you don't care about portability of your shell script and you could make them start with #!/usr/bin/fish to be fish scripts. Then they won't work on systems without fish.
Also, the system(3) C standard library function uses /bin/sh -c.
I enjoyed very much Yann Regis-Gianas' talk on POSIX [s]hell at FOSDEM2018.

How do I specify the Bourne shell (not sh)

I am writing a script and I want it to start with the Bourne shell. As I understand it, starting the script with:
#! /bin/sh
will not always specify the Bourne shell, but whatever the OS links to /bin/sh. Is there a way to explicitly specify Bourne?
Thanks!
The original Bourne Shell is not open source, so if you don't already have it, you're SOL.
If you do already have it, just put the location in the shebang.
Simple as that.
<Reminisce_mode_on>
Place a colon (:) on the first line. I used it on older systems
(A/UX, SCO Unix, Interactive Unix System V Release 3.2 SVR3, circa
1989, comes to mind) as the first character in a file to denote a
Bourne Shell script. It was also recognised by Thompson Toolkit's Korn
Shell (DOS > v3.2 ). Allowed Unix programmers to shell program in the
PC environment (DOS/WindowsNT).
</Reminisce_mode_off> Yeah, I'm old. Unix programmers never die, they just become zombie processes.
Depends on what you mean by "Bourne Shell".
Original Bourne Shell, which I believe is not what you are after:
proprietary, very limited, and only available on some true UNIX
systems, such as Solaris, derived from the original AT&T UNIX code.
#!/bin/sh is the way to get this non-portable shell.
Its ability to run true legacy scripts, and its smallness,
are about the only assets it has in my mind.
Today's memory gives the size asset less appeal.
Modern shells based on Bourne shell syntax. As opposed to, say csh.
bash, ksh, zsh are some. Bash is common in Linux environments, and yes, /bin/sh tends to link to one of these.
To use a specific shell, use something like which $SHELL to
get an absolute path.
#!/bin/env bash is less dependent on the shuffling of paths
found in different operating systems.
But this portable trick has the risk of choosing
the wrong shell if PATH is not set well enough and
does not allow arguments, such as -x, on the shell.
It has the advantage
of PATH being able to control which of several shells you use if
different versions of the same shell are available, which
ksh is well noted for.
So, if you want more help you will really need to detail the application you are after, and your definition of "Bourne Shell".

Automation on Windows with Bash like syntax

Is there a way that we can write automation scripts in bash syntax and run it on Windows host (We can call the executable file .exe of Windows). The Windows batch syntax looks quite complex :D
Any suggestions are appreciated.
You can use cygwin or mingw sys for this.
They are both just BASH implementation available on WinXX (actually they are much more, but you need now only bash).
But there are some differences:
cygwin uses its own file system hierarchy, with Win drives mapped to a part. subdirs. All related to file names is more unix-style. There are some problems with passing pathnames to Windows programs.
MinGW is more Windows friendly, file paths are like in Windows, less problems with Windows native programs.
You should try yourself and choose what you need.
You could install cygwin and run bash.
You can get a win32 port of bash. Cygwin is enormous, but native windows bash and a few utilities can be had for a much smaller footprint.
Start with UnxUtils, which includes a sh based on zsh (it's quite slow, though).
If that's not enough you can get a win32 bash from some places, though most are older versions.

how to start a new session in a shell script in platforms other than Linux?

I have this problem:
I have a script A, and it calls another script B, but this script B must run in another session, it is an easy job to do in a C program with setsid
(), but I cannot find an equivalent shell command. There is a setsid shell
command in Linux, but there are no such commands in AIX and other UNIX
platforms. Can anyone give me some advice on how to do it in AIX and other UNIX platforms? Thank you.
The setsid() system call exists in FreeBSD and OpenSolaris, and is part of POSIX.1. So I would think that it should exist in anything that claims to be POSIX-compliant.
AIX is fully compliant with "one or more" of the POSIX standards, but I've never used it, so I can't comment on it directly. Since it's a vendor-supported operating system, I recommend you touch base with your vendor.
Now.. What do you mean by "an equivalent shell command"? What do you mean by "session" in the context of a shell script? If what you're looking for is a way to run a second shell script with a separate controlling terminal from the original script, I suggest you look at GNU Screen instead of system calls. Screen should be available for AIX.
If you have a shell script that currently works for you in Linux, and you're trying to port it to other platforms, then include the script in your question. Otherwise, we're flying blind.

Bash or Bourne Scripts?

Is it better practice to write Bash scripts or Bourne scripts? My team writes Bourne scripts but I am not entirely sure why.
If this is a holy war question (ie: vim vs. emacs) please just reply: holy war.
It depends on what your target platform is.
If you're only targeting, say, major Linux distributions and Mac OS X, then you can be confident that these systems will have bash available. On other UNIXes (e.g., AIX, Solaris, HP-UX), bash may not necessarily be present, so Bourne is the safer choice. If bash is available, I can think of no reason you might prefer Bourne.
You can be more sure that Bourne shell will be installed on any given Unix computer. Yeah, Bash is ubiquitous on Linux, but the whole world isn't Linux.
The most important thing is to remember that not every OS softlinks /bin/sh to /bin/bash, as some Linux distros do. A lot of scripts are written for bash but begin with:
#!/bin/sh
so that they break e.g. in Ubuntu. So, when you write bash script, always write:
#!/bin/bash
Well, is a matter of taste, but for starters, bourne shell scripts can be run with bash, and I think bash has features that cannot be run by Bourne.
I use Bash as my login shell, but for scripting I'd choose the Bourne shell any day of the week and twice on Sunday. Bash has better features, better user friendliness and better bugs.
Actually, the same stuff that makes me choose Bash when I'm logging in, makes me avoid it when scripting. Bash tries to make everything nice and cozy for the user, but at the expense of a 776 kB executable (on my machine), compared to 140 kB for Bourne shell. Why would my script care about user friendliness? Any gain I might achieve through the use of some clever Bash function is effectively cancelled out by the shell footprint, which is more than five times as big.
I have computers running Linux, FreeBSD and OS X. Although I rarely move anything between the computers, it's nice to have the possibility. In a Bourne shell script, you simply type
#!/bin/sh
and it just works. Always. Bash might be common on Linux, but it's not as standardized as the Bourne shell. On FreeBSD, Bash is not installed by default. It can be installed from Ports if the sysadmin thinks it's a good idea but, even then, it ends up in /usr/local/bin/bash (not /bin/bash). Thus, if you still decide to go with Bash, you should write
#!/usr/bin/env bash
to make the script portable. env will find the shell for you, regardless of your Unix flavor (as long as it's installed).
At the end of the day, it's your choice. Just make sure that your scripts are actually compliant to the shell you choose, and not relying on "sh" being symlinked to "bash" or something similar.
Portability. I write #!/bin/sh unless things get really to painful, and then I write #!/bin/bash. The world is changing very rapidly, and I'm betting that in the future it will be easy to convince sysadmins to install bash. But I hedge my bets by using Bourne for most stuff, which is simple.
On Mac OS X /bin/sh is NOT a Bourne shell. (But you may get a true bournesh over at freshmeat).
To identify a traditional Bourne shell you may try to use the circumflex ^ (caret) as a replacement for | (pipe).
See:
The Traditional Bourne Shell Family,
http://www.in-ulm.de/~mascheck/bourne/
I'd go for bourne again shell, as the bourne shell can be slightly different among unix implementations. With bash you can be sure that bash is always bash.

Resources