* Re: add 'sudo' to 'mv' if file isn't writable by $USER
2011-09-14 22:19 add 'sudo' to 'mv' if file isn't writable by $USER TJ Luoma
@ 2011-09-15 3:30 ` Benjamin R. Haskell
2011-09-15 18:20 ` TJ Luoma
0 siblings, 1 reply; 3+ messages in thread
From: Benjamin R. Haskell @ 2011-09-15 3:30 UTC (permalink / raw)
To: TJ Luoma; +Cc: Zsh Users
[-- Attachment #1: Type: TEXT/PLAIN, Size: 2203 bytes --]
On Wed, 14 Sep 2011, TJ Luoma wrote:
> I'm wondering if someone has already done this.
>
> I have a function which does this:
>
>
> move () {
> command which -s gmv
> if [ "$?" = "0" ]
> then
> gmv --verbose --backup=numbered $@
> else
> mv -v -i $@
> fi
> }
>
> (simply put: use 'gmv' if it exists, otherwise use 'mv')
>
> That works pretty well (although if there are ways to do it better,
> please let me know).
There's a pretty common zsh idiom to avoid the use of 'which' or 'where':
(( $+commands[command-name] ))
So:
move () {
if (( $+commands[gmv] )) ; then
gmv --verbose --backup=numbered $@
else
mv -v -i $@
fi
}
> HOWEVER, now I want to do
>
> "If $FILE is writable by $USER, do 'move' as above. ELSE use 'sudo'
> before the mv or gmv command"
>
> I can probably cobble together a solution, but I thought I'd check
> first to see if someone here had already invented this wheel.
For some things, I have it set up to:
1. try to do the thing
2. if it fails, try with sudo
E.g.:
mkdirp () { mkdir -p $argv || sudo mkdir -p $argv }
You get an extra warning when sudo's needed, but sometimes that's useful
info. And the code's pretty simple. (Not sure why I prefer $argv over
$@, exactly.) Maybe dangerous in the case of a move (if some, but not
all, of the files are successfully moved without sudo).
For this particular problem, maybe something along the lines of:
move () {
local -a cmd
# check that destination is writable
# or destination doesn't exist, but its dir is writable
# otherwise, need sudo
[[ -w $argv[-1] ]] || [[ ( ! -e $argv[-1] ) && -w ${argv[-1]}:h ]] || cmd+=( sudo )
if (( $+commands[gmv] )) ; then
cmd+=( gmv --verbose --backup=numbered )
else
cmd+=( mv -v -i )
fi
$cmd $argv
}
In a lot of cases, I would probably shorten:
if (( $+commands[blah] )) ; then
# x
else
# y
fi
when x and y both always return true¹, to:
(( $+commands[blah] )) && x || y
But that makes for a pretty long line here:
(( $+commands[gmv] )) && cmd+=( gmv --verbose --backup=numbered ) || cmd+=( mv -v -i )
--
Best,
Ben
¹: for most values of "always"
^ permalink raw reply [flat|nested] 3+ messages in thread