cp: illegal option -- b on mac - macos

I'm looking to backup a file. If the file exists in backup form, I'm looking to create a new version of that filename so as not to overwrite the previous backup.
I believe:
cp -b ~/.profile ~/
cp --backup ~/.profile ~/
is exactly what I need. However these options aren't available on a mac. Does anyone know if a substitute exists on a mac?

Easiest thing to do is install GNU cp. The easiest way to do that is install Homebrew:
ruby -e \
"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew install coreutils
Then you can use gcp instead of cp whenever you need features not in the BSD cp that's part of OS X, e.g. gcp --backup.

Related

Brew stops working after terminal session is closed

I have installed Brew in MACOS Monterey with the following commands.
mkdir homebrew && curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew
eval "$(homebrew/bin/brew shellenv)"
brew update --force --quiet
chmod -R go-w "$(brew --prefix)/share/zsh"
I have tested it after the install, and it works, however closing the terminal session and opening it again causes terminal to say that the command brew is not found after running it. I can still see the homebrew directory, so Im guessing its in the wrong place for terminal to run it.
The only supported method to install brew is found on brew.sh:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Ok I was able to fix the issue by adding the PATH to the .bash_profile file.

Find the install location of brew on OS X

I'm creating a BASH scrip which requires a couple of applications to be installed. ffmpeg and sox
To ensure they are in place when my script runs I first check for the installation of Homebrew with :
#!/bin/bash
which -s brew
if [[ $? != 0 ]] ; then
# Install Homebrew
/usr/bin/ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
fi
Then I check that sox and ffmpeg are installed with :
echo "---- checking for sox ----"
which -s sox || /usr/local/bin/brew install sox
echo "---- checking for ffmpeg ----"
which -s ffmpeg || /usr/local/bin/brew install ffmpeg
The problem I am facing is when Homebrew is installed but in a non-standard location.
I have to use the full path to Homebrew because this script is being run within Playtypus.
So the question is : How can I reliably get the installed path of Homebrew in a BASH script?
Answering my own question...
You can test the output of which brew and deal with things accordingly. To gracefully deal with the case where Homebrew is not installed you can use if which brew 2> /dev/null which redirects stderr to /dev/null.
brew --prefix is also useful here as it give the path to where Homebrew installed applications are symlinked to, rather than their actual install path.
A script which works and shows this working :
#!/bin/bash
if which brew 2> /dev/null; then
brewLocation=`which brew`
appLocation=`brew --prefix`
echo "Homebrew is installed in $brewLocation"
echo "Homebrew apps are run from $appLocation"
else
echo "Can't find Homebrew"
echo "To install it open a Terminal window and type :"
echo /usr/bin/ruby -e \"\$\(curl\ \-fsSL\ https\:\/\/raw\.github\.com\/Homebrew\/homebrew\/go\/install\)\"
fi
Thanks to Allendar for the pointers.
Just to add to this, Homebrew's --prefix mode has been enhanced here in the far-flung future of 2020 (or maybe it was always this way), so that it now takes a package name as an argument. Meaning locating those "keg-only" packages which aren't linked into standard paths is as easy as:
$ brew --prefix ffmpeg
/usr/local/opt/ffmpeg

cp --parents option on mac

On Linux, I have a --parents option available for the cp command so I can do
cp --parents test/withintest/go.rb test2
http://www.gnu.org/software/coreutils/manual/html_node/cp-invocation.html
On Mac, I do not have this option available. Is there a way to do this on Mac? Why is this option not available?
PS. The purpose of --parents is the following:
‘--parents’ Form the name of each destination file by appending to the
target directory a slash and the specified name of the source file.
The last argument given to cp must be the name of an existing
directory.
For example, the command:
cp --parents a/b/c existing_dir
copies the file a/b/c to existing_dir/a/b/c, creating any missing intermediate directories.
This bothered me quite a lot as well.
A workaround for this could be to use rsync.
rsync -R test/withintest/go.rb test2
has the same effect as cp --parents and OS X comes standard with rsync.
You can use the ditto command on Mac OS X:
The basic form
ditto <src-path> <dst-path>
does what you want. There's a lot more options too - check out the man page.
You can install the GNU version of cp using MacPorts.
After MacPorts is installed you can install the coreutils packages:
sudo port install coreutils
Then you will be able to use the GNU version cp and other core utilitites (ls, date, cat, etc.) by prefixing the command with a g:
gcp --parents test/withintest/go.rb test2
If you want these GNU versions to be used by default you can add the GNU bin update your path. Add the following to your ~/.bash_profile:
export PATH="/opt/local/libexec/gnubin:$PATH"
The Homebrew way:
Install coreutils
brew install coreutils
Use the GNU g- prefixed command
gcp --parents test/withintest/go.rb test2
I used rsync and what I did was:
rsync -R dir/**/file.json destination
Try
mkdir -p `dirname "$file_path"` && cp "$old_dir/$file_path" "$file_path"
This first creates the directory with all itermediates in the relative file path. Then it copies the file to the newly created directory.
I would not replace mac cp with GNU cp. I would also not used ditto because it is not cross-platform. Instead use cross-platform tools, such as rsync:
rsync <srcDir/srcFile> <dst>
Result: dst/srcDir/srcFile

Bash copy verbose update in Solaris

I'm writing some small bash scripts for copiyng certain files/directories in GNU/Linux and Solaris. Everything is OK in Linux, but cp command hasn't the same options in Linux and Solaris.
Copy command is something like this:
cp -ruv $source $dest
Unfortunately I don't know how to achieve copy verbose and copy update in Solaris. Any idea?
Thanks
Unfortunately, cp under Solaris doesn't have that option. man solaris should reveal that.
Are you comfortable making your script depend on rsync?
Or, if possible, you can install the coreutils package and use GNU's cp.
I ran into a similar issue myself and found that gcp takes care of it too. I've made installing coreutils part of my standard system setup.
I run these on a new Solaris install:
pkgadd -d http://get.opencsw.org/now
pkgutil -U
pkgutil -i -y coreutils
pkgutil -a vim
pkgutil -i -y vim
pkgutil -i -y findutils
Remember to add the path - and the documentation path - to your profile, and possibly to the system profile at /etc/profile:
# Set the program path
PATH=$PATH:/usr/sfw/bin:/usr/sfw/sbin:/usr/openwin/bin:/opt/csw/bin:/usr/ccs/bin:/usr/local/bin:/usr/local
export PATH
# Set the documentation path
MANPATH="$MANPATH:/usr/share/man:/opt/sfw/man:/opt/csw/man"
export MANPATH
It sounds like you might be new to Solaris - as I am relatively new. I also do these, which shouldn't affect anything.
I set VIM as the default editor instead of VI - it's compatible, but has more features, including ANSI color, and some terminal emulators will pass your mouse clicks and scrolling through for even more flexibility:
# Set the default editor
EDITOR=vim
export EDITOR
Then if you are still using the default prompt that doesn't say anything, you might want to add some information - this version requires a Bash shell:
# Set the command prompt, which includes the username, host name, and the current path.
PS1='\u#\h:\w>'
export PS1
To recreate verbose mode, you can tee the output to the controlling terminal (/dev/tty) while the stdoout output of tee itself is passed to cp via xargs.
find /some/source/directory -type f | \
tee /dev/tty | xargs -I {} cp {} /copy/to/this-directory/
Replace the find with whatever you like, so long as it passes the paths to the files to be copied through the pipe to tee.
Tested on a standard Solaris 10 system without extra GNU utils.

error when switching to directory: "perl version 5.12.3 can't run /usr/bin/shasum"

I installed rvm 1.9.3 and now whenever I switch to a directory containing a .rvmrc, I get a perl error message:
~/example$ cd .. && cd example
perl version 5.12.3 can't run /usr/bin/shasum. Try the alternative(s):
/usr/bin/shasum5.10.0 (uses perl 5.10.0)
Run "man perl" for more information about multiple version support in
Mac OS X.
You may try this dirty approach. This approach will skip those check and directly use shasum in your binary directory
$ cd /usr/bin
$ ls shasum*
shasum shasum5.10.0
$ mv /usr/bin/shasum /usr/bin/your_backup_shasum
$ ln -s shasum5.10.0 shasum

Resources