tags:

views:

1414

answers:

20

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.

A: 

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 {} \;
DeletedAccount
The correct way to do this is: find ~ -group vboxusers -exec chown kent:kent {} \;
Neil
If you have more than 4096 results, your script will fail with xargs.
Neil
Thank you for pointing it out, I've change the solution above to yours.
DeletedAccount
A: 

Too long to include in total, but the solutions to How do I manipulate $PATH elements in shell scripts? are quite useful to me...

dmckee
+8  A: 

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,

Rob Wells
pretty much essential. You can always override it by using rm -f
Chris Huang-Leaver
@Chris, yep. I was more interested in showing how to disable aliased commands temporarily though. (-:
Rob Wells
+2  A: 

This is not so useful, but really interesting:

history | awk '{print $2}' | awk 'BEGIN {FS="|"}{print $1}' | sort | uniq -c | sort -n | tail | sort -nr

It prints the 10 most used commands.

EDIT: This question is really similar to this.

fmartin
A: 

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

Cfreak
for svn there's also `svn export`, which exports the working directory and leaves the .svn folders as is
knittl
The correct way to do this is:find . -type d -name .svn -exec rm -rf {} \;
Neil
If you have more than 4096 results, your script will fail with xargs.
Neil
+8  A: 

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".

Robert Gowland
Not to mention this snippet's cousin: MYVAR=${OTHER_VAR:=default} which sets the value of OTHER_VAR to default if it is unset. Above only uses the default only uses the default value in this instance and leaves $1 unset.
Rob Wells
+1  A: 

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 '{}' \;
Does not work in Linux.
Neil
+5  A: 

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
Nate Kohl
I never knew about `cd -`, thanks! That looks like it might help.
Zifre
ick... I always hate seeing `seq i j` and `jot j i`. Modern bash has range expansions: for n in {1..100}; do ...
guns
why do you have a directory called /i/am/a/banana ? ;)
Stefano Borini
@Stefano: http://www.youtube.com/watch?v=MuOvqeABHvQ
Nate Kohl
A: 

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
}
+2  A: 

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...
Dennis Williamson
A: 
: > truncate-file-to-zero-bytes.txt    # without changing its permissions

See: codesnippets.joyent.com/posts/show/2067

+1  A: 

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
DeletedAccount
+2  A: 

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
amarillion
Nice one! I've been wondering about how to detect root from a script. :-)
DeletedAccount
A: 

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.

DeletedAccount
A: 

An effective (and intuitive) way to get a full canonical file path given a specified file. This would resolve all cases of symbolic links, relative file references, etc.

full_path="$(cd $(/usr/bin/dirname "$file"); pwd -P)/$(/usr/bin/basename "$file")"
A: 

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
Don Branson
A: 

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.

DeletedAccount
A: 
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 #
ongoto
A: 
 !find:p  ......... show last find command - not execute
 # create one dir and go to
 echo 'mkcd() { mkdir -p "$@" && cd $_; }' >> ~/.bashrc  

 # backup file in single command
 cp /path/too/long/to/file{,.backup}
A: 

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.

Gordon Broom