Hi,
We've had these for a lot of other languages. The one for C/C++ was quite popular, so was the equivalent for Python. I thought one for BASH would be interesting too.
To change all files in ~ which are owned by the group vboxusers to be owned by the user group kent instead, I created something. But as it had a weakness in using xargs I'm changing it to the solution proposed in the comment to this answer:
$ find ~ -group vboxusers -exec chown kent:kent {} \;
Too long to include in total, but the solutions to How do I manipulate $PATH elements in shell scripts? are quite useful to me...
G'day,
My favourite, and it's applicable to other shells that support aliases, is the simple way of temporarily disabling an alias by prepending a backslash to a command.
So:
alias rm='rm -i'
would always give you interactive mode when entering rm, entering
\rm
on the command line bypasses the alias.
HTH
cheers,
We develop websites and store code for them in SVN. When moving to production we don't want the .svn directories to show up. The following code recurses directories and removes unwanted ones (could be used for any unwanted directories). Not strictly bash but useful nonetheless.
find . -type d -name .svn | xargs rm -rf
execute from the top most path in the product ... of course be careful as executed in the wrong place could cause very bad things to happen.
You could also do a regular file by changing -type d to -type f
In a BASH script, assign an argument to variable but provide a default if it exists:
MYVAR=${1:-default}
$MYVAR will contain the first argument if one was given else "default".
To remove .svn directories you may also use the combination 'find...-prune...-exec...' (without xargs):
# tested on Mac OS X
find -x -E . \( -type d -regex '.*/\.svn/*.*' -prune \) -ls # test
find -x -E . \( -type d -regex '.*/\.svn/*.*' -prune \) -exec /bin/rm -PRfv '{}' \;
There's cd -
to go to the previously-visited directory:
/usr/local/bin> cd /i/am/a/banana
/i/am/a/banana> cd -
/usr/local/bin>
...and then there are all those useful incarnations of the BASH for-loop:
for file in *.txt; do ls $file; done
for item in `echo foo bar baz`; do echo $item; done
for num in `seq 0 9`; do echo $num; done
Found this somewhere on the net a long time ago:
function bashtips {
cat <<EOF
DIRECTORIES
-----------
~- Previous working directory
pushd tmp Push tmp && cd tmp
popd Pop && cd
GLOBBING AND OUTPUT SUBSTITUTION
--------------------------------
ls a[b-dx]e Globs abe, ace, ade, axe
ls a{c,bl}e Globs ace, able
\$(ls) \`ls\` (but nestable!)
HISTORY MANIPULATION
--------------------
!! Last command
!?foo Last command containing \`foo'
^foo^bar^ Last command containing \`foo', but substitute \`bar'
!!:0 Last command word
!!:^ Last command's first argument
!\$ Last command's last argument
!!:* Last command's arguments
!!:x-y Arguments x to y of last command
C-s search forwards in history
C-r search backwards in history
LINE EDITING
------------
M-d kill to end of word
C-w kill to beginning of word
C-k kill to end of line
C-u kill to beginning of line
M-r revert all modifications to current line
C-] search forwards in line
M-C-] search backwards in line
C-t transpose characters
M-t transpose words
M-u uppercase word
M-l lowercase word
M-c capitalize word
COMPLETION
----------
M-/ complete filename
M-~ complete user name
M-@ complete host name
M-\$ complete variable name
M-! complete command name
M-^ complete history
EOF
}
Add a space (or other delimiter) only if a variable is set, in order to avoid ugly unnecessary spaces.
$ first=Joe
$ last= # last name blank, the following echoes a space before the period
$ echo "Hello, $first $last. Welcome to..."
Hello, Joe . Welcome to...
$ echo "Hello, $first${last:+ $last}. Welcome to..."
Hello, Joe. Welcome to...
$ last=Green
$ echo "Hello, $first${last:+ $last}. Welcome to..."
Hello, Joe Green. Welcome to...
Here is another one:
#!/bin/bash
# Shows the full path of files, good for copy pasting and for when
# listing the full paths is necessary.
# Usage: Run in the working directory (no path), otherwise takes the
# same file specification as ls.
for file in $(ls "$@"); do
echo -n $(pwd)
[[ $(pwd) != "/" ]] && echo -n /
echo $file
done
At the beginning of a script that must be run as root:
if [ `id -u` != 0 ]; then
echo "This script must be run as root" 1>&2
exit 1
fi
I use this to indent source code by four spaces and copying the result to the clipboard in X:
cat src/Something.java | sed -e 's/^/ /g' | xsel
Now Something.java is ready to be pasted by middle clicking. I know I can reduce the expression by one pipe and remove the cat, but I like it this way as I find it easier edit the beginning when re-using the expression.
I use this one a lot in conjunction with Java development:
#!/bin/sh if [ "$1" == "" ] || [ "$2" == "" ]; then echo "Usage jarfinder.sh " exit fi SEARCH=`echo $2 | sed -e 's/[\\\/]/./g'` echo Searching jars and zips in $1 for "$SEARCH" find $1 -type f -printf "'%p'\n" | egrep "\.(jar|zip)'$" | sed -e "s/\(.*\)/echo \1 ; jar tvf \1 | sed -e 's\/^\/ \/' | grep -i \"$SEARCH\"/" | sh
which I keep in my collection of handy scripts.
I also use this one-liner a lot:
find . -name "*.java" | xargs grep -li "yadayada"
end this one:
find . -name "*.java" | sed -e 's+\(.*\)+echo \1 ; yada_cmd \1+' | sh
Here is a nice grep expression to remove blank lines and comment lines:
cat /etc/ssh/sshd_config | grep -v '^[ \t]*$\|^[ \t]*#'
The above will display the used settings in sshd_config without any clutter.
hello
I use this to launch apps in their own xterm window (or not) from the same link.
#!/bin/bash
#
# cli_app launcher -- detects where u are launching from; gui/tty
#
dev=`/usr/bin/tty`
case $dev in
/dev/pts/0 | /dev/pts/1) xterm -e /home/user/bin/cli_app ;; ## opens gui terminal
*) /home/user/bin/cli_app ;; ## opens where u are
esac
# eof #
If you like to have your current working directory in your prompt ($PS1
), are running in a terminal with only 80 columns, and sometimes work in really deep hierarchies, you can end up with a prompt that takes all but about 5 characters of your line. In that case, the following declarations are helpful:
PS1='${PWD##$PREFIX}$ '
PREFIX='' export PREFIX
prefix () {
PREFIX="$1"
}
prefix '*/'
The prefix '*/'
call will set your prompt to only contain the last directory element of your current working directory (instead of the complete path). If you want to see the entire path, call prefix
with no arguments.