commandlinefu.com is the place to record those command-line gems that you return to again and again.
Delete that bloated snippets file you've been using and share your personal repository with the world. That way others can gain from your CLI wisdom and you from theirs too. All commands can be commented on, discussed and voted up or down.
If you have a new feature suggestion or find a bug, please get in touch via http://commandlinefu.uservoice.com/
You can sign-in using OpenID credentials, or register a traditional username and password.
First-time OpenID users will be automatically assigned a username which can be changed after signing in.
Every new command is wrapped in a tweet and posted to Twitter. Following the stream is a great way of staying abreast of the latest commands. For the more discerning, there are Twitter accounts for commands that get a minimum of 3 and 10 votes - that way only the great commands get tweeted.
» http://twitter.com/commandlinefu
» http://twitter.com/commandlinefu3
» http://twitter.com/commandlinefu10
Use your favourite RSS aggregator to stay in touch with the latest commands. There are feeds mirroring the 3 Twitter streams as well as for virtually every other subset (users, tags, functions,…):
Subscribe to the feed for:
Bash snippet to force GNU/Linux keyboard settings, layout and configuration.
Usefull when some GNU/Linux distributions such as *Ubuntu's store only limited configation options due to demonstration purposes on LiveUSB or Live persistent devices.
Overcomes the English QWERTY to French AZERTY settings failure.
Code bash en ligne de commande pour forcer l'adoption du clavier AZERTY sur les cl? USB bootable en Ubuntu.
tail() { thbin="/usr/bin/tail"; if [ "${1:0:1}" != "-" ]; then fc=$(($#==0?1:$#)); lpf="$((($LINES - 3 - 2 * $fc) / $fc))"; lpf="$(($lpf<1?2:$lpf))"; [ $fc -eq 1 ] && $thbin -n $lpf "$@" | /usr/bin/fold -w $COLUMNS | $thbin -n $lpf || $thbin -n $lpf "$@"; else $thbin "$@"; fi; unset lpf fc thbin; }
This is a function that implements an improved version of tail. It tries to limit the number of lines so that the screen is filled completely. It works with pipes, single and multiple files. If you add different options to tail, they will overwrite the settings from the function.
It doesn't work very well when too many files (with wrapped lines) are specified.
Its optimised for my three-line prompt.
It also works for head. Just s/tail/head/g
Don't set 'thbin="tail"', this might lead to a forkbomb.
Run the alias command, then issue
ps aux | tail
and resize your terminal window (putty/console/hyperterm/xterm/etc) then issue the same command and you'll understand.
${LINES:-`tput lines 2>/dev/null||echo -n 12`}
Insructs the shell that if LINES is not set or null to use the output from `tput lines` ( ncurses based terminal access ) to get the number of lines in your terminal. But furthermore, in case that doesn't work either, it will default to using the default of 80.
The default for TAIL is to output the last 10 lines, this alias changes the default to output the last x lines instead, where x is the number of lines currently displayed on your terminal - 7. The -7 is there so that the top line displayed is the command you ran that used TAIL, ie the prompt.
Depending on whether your PS1 and/or PROMPT_COMMAND output more than 1 line (mine is 3) you will want to increase from -2. So with my prompt being the following, I need -7, or - 5 if I only want to display the commandline at the top. ( http://www.askapache.com/linux/bash-power-prompt.html )
275MB/748MB
[7995:7993 - 0:186] 06:26:49 Thu Apr 08 [askapache@n1-backbone5:/dev/pts/0 +1] ~
In most shells the LINES variable is created automatically at login and updated when the terminal is resized (28 linux, 23/20 others for SIGWINCH) to contain the number of vertical lines that can fit in your terminal window. Because the alias doesn't hard-code the current LINES but relys on the $LINES variable, this is a dynamic alias that will always work on a tty device.
Take a file and ,."()?!;: give a list of all the words in order of increasing length.
First of all use tr to map all alphabetic characters to lower case and also strip out any puntuation.
A-Z become a-z
,."()?!;: all become \n (newline)
I've ignored - (hyphen) and ' (apostrophe) because they occur in words.
Next use bash to print the length ${#w} and the word
Finally sort the list numerically (sort -n) and remove any duplicates (sort -u).
Note: sort -nu performs strangely on this list. It outputs one word per length.
Bash only, no sed, no awk. Multiple spaces/tabs if exists INSIDE the line will be preserved. Empty lines stay intact, except they will be cleaned from spaces and tabs if any available.
Says time every 5 seconds in hours, minutes and seconds using festival.
Just like "!$", except it does it instantly. Then you can hit enter if you want.
Don't do this:
echo word | command
Using a bash "here strings" and "here documents" look leeter than piping echo into the command. Also prevents subshell execution. Word is also expanded as usual.
Sometimes, you don't want to just replace the spaces in the current folder, but through the whole folder tree - such as your whole music collection, perhaps. Or maybe you want to do some other renaming operation throughout a tree - this command's useful for that, too.
To rename stuff through a whole directory tree, you might expect this to work:
for a in `find . -name '* *'`;do mv -i "$a" ${a// /_};done
No such luck. The "for" command will split its parameters on spaces unless the spaces are escaped, so given a file "foo bar", the above would not try to move the file "foo bar" to "foo_bar" but rather the file "foo" to "foo", and the file "bar" to "bar". Instead, find's -execdir and -depth arguments need to be used, to set a variable to the filename, and rename files within the directory before we rename the directory.
It has to be -execdir and won't work with just -exec - that would try to rename "foo bar/baz quux" to "foo_bar/baz_quux" in one step, rather than going into "foo bar/", changing "baz quux" to "baz_quux", then stepping out and changing "foo bar/" into "foo_bar/".
To rename just files, or just directories, you can put "-type f" or "-type d" after the "-depth" param.
You could probably safely replace the "mv" part of the line with a "rename" command, like rename 'y/ /_/' *, but I haven't tried, since that's way less portable.
Useful contexts :
You are doing yoga or some other physical training in which you are holding a position.
Or you practice the pomodoro productivity technique.
Or your girlfriend said "We're leaving in 40 minutes".
Design details:
sleep executes before espeak to give you a 5 seconds head start.
espeak is run in the background so it doesn't mess up the timing.
Applies each file operator using the built-in test.
testt /home/askapache/.sq
/home/askapache/.sq
-a True - file exists.
-d True - file is a directory.
-e True - file exists.
-r True - file is readable by you.
-s True - file exists and is not empty.
-w True - the file is writable by you.
-x True - the file is executable by you.
-O True - the file is effectively owned by you.
-G True - the file is effectively owned by your group.
-N True - the file has been modified since it was last read.
Full Function:
testt ()
{
local dp;
until [ -z "${1:-}" ]; do
dp="$1";
[[ ! -a "$1" ]] && dp="$PWD/$dp";
command ls -w $((${COLUMNS:-80}-20)) -lA --color=tty -d "$dp";
[[ -d "$dp" ]] && find "$dp" -mount -depth -wholename "$dp" -printf '%.5m %10M %#15s %#9u %-9g %#5U %-5G %Am/%Ad/%AY %Cm/%Cd/%CY %Tm/%Td/%TY [%Y] %p\n' -a -quit 2> /dev/null;
for f in a b c d e f g h L k p r s S t u w x O G N;
do
test -$f "$dp" && help test | sed "/-$f F/!d" | sed -e 's#^[\t ]*-\([a-zA-Z]\{1\}\) F[A-Z]*[\t ]* True if#-\1 "'$dp'" #g';
done;
shift;
done
}
Here is the full function (got trunctated), which is much better and works for multiple queries.
function cmdfu () {
local t=~/cmdfu;
until [[ -z $1 ]]; do
echo -e "\n# $1 {{{1" >> $t;
curl -s "commandlinefu.com/commands/matching/$1/`echo -n $1|base64`/plaintext" | sed '1,2d;s/^#.*/& {{{2/g' | tee -a $t > $t.c;
sed -i "s/^# $1 {/# $1 - `grep -c '^#' $t.c` {/" $t;
shift;
done;
vim -u /dev/null -c "set ft=sh fdm=marker fdl=1 noswf" -M $t;
rm $t $t.c
}
Searches commandlinefu for single/multiple queries and displays syntax-highlighted, folded, and numbered results in vim.
This command uses ping to get the routers' IP addresses to the destination host as traceroute does. If you know what I mean..
regenerateCSR original.crt new.key new.csr
Mac install ssh-copy-id
From there on out, you would upload keys to a server like this:
(make sure to double quote the full path to your key)
ssh-copy-id -i "/PATH/TO/YOUR/PRIVATE/KEY" username@server
or, if your SSH server uses a different port (often, they will require that the port be '2222' or some other nonsense:
(note the double quotes on *both* the "/path/to/key" and "user@server -pXXXX"):
ssh-copy-id -i "/PATH/TO/YOUR/PRIVATE/KEY" "username@server -pXXXX"
...where XXXX is the ssh port on that server
I have used single packet, and in a silent mode with no display of ping stats. This is with color and UI improvement to the http://www.commandlinefu.com/commands/view/10220/check-if-a-machine-is-online. It is as per the enhancements suggested.