Adding flags and existing commands
Commands that exist as already compiled binary files cannot be modified, so adding flags is impossible. Of course, one could attempt to modifying the binary data of the executable itself, but that's obscenely difficult and impractical. More practical would be to obtain source code, modify the source, and recompile the command. In case the command is a script (Perl, Python, shell,etc), you can modify it directly with the root privileges. However, all these methods have issues in common:
- Modifying a command might be against licensing terms. Very often readers of the answers on this site assume everything is open source and libre under Ubuntu, but proprietary software is also used. Of course, you can modify any software - that's not the question of ability or coding competence. Very often the question is whether you may modify it.
- Portability, in the sense that this flag works on this machine where you modified it but not another. Tangentially, documentation. Imagine you wrote a script which uses the modified version of
seq
, but whatever flag you added is not in the man page. Your coworker or another person who will be reading this script will be very confused as to why that flag isn't in the manual, and maybe even more confused as to why the flag doesn't work; even more fun is when you have whole set of utilities that may depend on that particular command with that particular flag. This may make your coworkers very unhappy. And if you redistribute (that is give them) the copy of your modified command, now you have licensing problems (IANAL, but this can lead to lawsuits).
- Going back to the topic of coworkers, modifying a command that should be standard may break their workflow and mess with the development environment.
Better solution
General idea for when you want to have a custom flag is to have a wrapper around the original command. That can be function in your ~/.bashrc
, a compiled program, a script - whatever. The key point is that it should be used only within your environment and you should be aware of when you're writing commands for yourself and when you're writing for commands to be used by others.
So here's some options/suggestions:
- Define function within your
~/.bashrc
. Functions take precedence over commands that are located in any directory in your PATH
variable.
- Naming should be unambiguous. For instance, naming your own
seq
the same would be ambiguous since functionality of two will differ. Better way would be to have my_seq
or seq_f
for function. Scripts typically have .sh
extension, so that should help with ambiguity.
- If you're modifying a compiled binary, let it live in your
~/bin
and maybe rename it.
- Consider using
~/bin/mycommand
instead of just mycommand
. As said in the presentation by Hendrik Jan Thomassen, original Unix commands were short because the keys on old PDP-11 terminals were hard to press. We don't have to worry about that nowadays, plus if you're putting that command in a script this means you won't have to retype it.
About rm --dry-run
GNU Coreutils are well known for rejecting features that already have certain similar implementations or can be achieved via combining with other utilities; for instance in df
the --no-header
flag is rejected because it can be done with sed
or other utility that can remove first line of text. And this makes sense.
As far as rm
goes, there already exists -i
flag for interactive, so it should prompt the user. Another frequent technique is to use echo
instead of any command for dry run. Thus the --dry-run
flag could be implemented via:
# Prompts for y/n answer every time
rm -i ./*
# Automates answering "n"
for f in ./*; do rm -i "$f" <<< "n"; done
# or for non-bash shells:
for f in ./*; do echo "n" | rm -i "$f"; done
# prints the command that would be executed
echo rm "$file"
All of these approaches can be combined with what I mentioned before - wrap a custom function or script around the original command. Something like:
saferm(){
case "$@" in
*--dry-run*) echo rm "$@";;
*) rm "$@";;
}
See also
find
, the FreeBSD version doesn't have some flags the GNU one has – Sergiy Kolodyazhnyy Sep 09 '18 at 18:44