UI / design
I respectfully reject the premise that this is an improvement on rsync
.
For an "easy" copy, almost any tool will be adequate,
including cp -r
and tar cf - . | (cd /some/where && tar xvf -)
--
that second one works well with ssh
pipelines.
But sometimes we need to worry about network mounts and "big" files.
In which case the twin spectres of "disk full" and CTRL/C interrupt are ever present.
In such cases, I tend to strongly value the fact that rsync
never exposes a partial copy to the destination filesystem.
It (roughly) will copy ReadMe as .123tmpReadMe, and do
an atomic rename
after all the bits have arrived.
That said, I do confess that rsync's distinction between
directory foo
and foo/
takes some getting used to,
so I would encourage writing a bash frontend script
which accepts whatever you feel would be an improved
syntax, and then issues an rsync command to get the work done,
revealing the command line args being used.
relative paths
# $2: Source relative path(s) to be copied; may be single files or directories; may contain wildcards; may contain '..', but not to undo Source root.
Thank you for writing such documentation comments, I appreciate it.
I'm afraid I failed to understand the meaning of "not to undo Source root".
I initially parsed it as a security related item, don't go above Source root?
But that doesn't seem relevant for a command line tool invoked by a trusted user.
Examples wouldn't hurt,
such as confirming that a **
recursive wildcard is supported.
The whole plural aspect of jamming "paths" and "files" into
the $2
parameter seems unfortunate.
Usual unix approach would be to put them at the end,
so we can have one or more without worrying about quoting details.
chdir
Maybe it's my limited imagination?
But I can't imagine why I would want that mandatory $1
argument.
Often I want bash TAB completion of pathnames,
so I cd
to the source directory, and now the command becomes dircp .
Or maybe I don't need completion,
so I type (cd /some/where && cp foo /baz)
.
For makefiles that works out to make -C /some/where target
;
consider adopting an optional -C dir
argument for dircp.
shebang
I assume you issued $ chmod a+x dircp
.
That should always go hand-in-hand with an initial
shebang.
For example:
#! /usr/bin/env bash
Also acceptable: #! /bin/bash
ls antipattern
if ! ls -d "$srcpath" ...
This crops up often enough that FAQ pages are devoted to it.
I imagine that [ -e "$srcpath" ]
would suffice.
Consult the test
man page for details.
(Kudos for getting the quoting correct here!)
quoting
In my opinion, bash
is not an easy language to author solid code in.
There's a lot of details, and punctuation.
Starting with quoting nonsense.
Please understand that echo "a b" c
is very different from echo a b c
.
Alas, it is all too easy for a SPACE embedded within a filename to be lost
in that way.
So we kind of have to be paranoid about quoting everything,
and shellcheck
can help.
Anything submitted to CodeReview should have already gone through
a relevant linter and passed it cleanly.
Here's the results I obtained.
In dircp.sh line 14:
if [ ! -d $1 ]; then
^-- SC2086 (info): Double quote to prevent globbing and word splitting.
Did you mean:
if [ ! -d "$1" ]; then
In dircp.sh line 25:
for srcpath in ${@:2:$#-2}; do
^---------^ SC2068 (error): Double quote array expansions to avoid re-splitting elements.
In dircp.sh line 30:
dstpath="$dstroot/${srcpath#$srcroot/}"
^------^ SC2295 (info): Expansions inside ${..} need to be quoted separately, otherwise they match as patterns.
Did you mean:
dstpath="$dstroot/${srcpath#"$srcroot"/}"
In dircp.sh line 31:
if ! (mkdir -p $(dirname "$dstpath") && cp -r "$srcpath" "$dstroot/${srcpath#$srcroot/}"); then
^-------------------^ SC2046 (warning): Quote this to prevent word splitting.
^------^ SC2295 (info): Expansions inside ${..} need to be quoted separately, otherwise they match as patterns.
Did you mean:
if ! (mkdir -p $(dirname "$dstpath") && cp -r "$srcpath" "$dstroot/${srcpath#"$srcroot"/}"); then
In dircp.sh line 36:
for srcpath in ${@:2:$#-2}; do
^---------^ SC2068 (error): Double quote array expansions to avoid re-splitting elements.
In dircp.sh line 37:
impl $1 $1/$srcpath ${!#} # expands unexpanded wildcards in $2
^-- SC2086 (info): Double quote to prevent globbing and word splitting.
^-- SC2086 (info): Double quote to prevent globbing and word splitting.
^------^ SC2086 (info): Double quote to prevent globbing and word splitting.
Did you mean:
impl "$1" "$1"/"$srcpath" ${!#} # expands unexpanded wildcards in $2
For more information:
https://www.shellcheck.net/wiki/SC2068 -- Double quote array expansions to ...
https://www.shellcheck.net/wiki/SC2046 -- Quote this to prevent word splitt...
https://www.shellcheck.net/wiki/SC2086 -- Double quote to prevent globbing ...
Recommend you tidy those up,
and then come back for a second pass.