Difference between revisions of "Bash Tips"
m (→History) |
|||
(17 intermediate revisions by 2 users not shown) | |||
Line 78: | Line 78: | ||
** Registering a custom function to complete command line of e.g. myprog: complete -F _myprog -o dirnames myprog |
** Registering a custom function to complete command line of e.g. myprog: complete -F _myprog -o dirnames myprog |
||
** Creating the custom function: |
** Creating the custom function: |
||
+ | <source lang=bash> |
||
_myprog() |
_myprog() |
||
{ |
{ |
||
Line 86: | Line 87: | ||
return 0 |
return 0 |
||
} |
} |
||
+ | </source> |
||
− | |||
==Misc== |
==Misc== |
||
Line 113: | Line 114: | ||
What is the output of this command? |
What is the output of this command? |
||
+ | <source lang=bash> |
||
− | <pre> |
||
echo one>/tmp/t;(echo two>/dev/stdout)>>/tmp/t;cat /tmp/t |
echo one>/tmp/t;(echo two>/dev/stdout)>>/tmp/t;cat /tmp/t |
||
− | </ |
+ | </source> |
Now, try... |
Now, try... |
||
Line 148: | Line 149: | ||
perl -e 'print scalar localtime(1141863326), "\n"' |
perl -e 'print scalar localtime(1141863326), "\n"' |
||
To keep the history "forever", here is a nice [http://www.onerussian.com/Linux/.files/.bashrc_history .bashrc_history] script to install |
To keep the history "forever", here is a nice [http://www.onerussian.com/Linux/.files/.bashrc_history .bashrc_history] script to install |
||
− | I adapted some stuff: |
+ | <br>I adapted some stuff: |
* Enable timestamps on individual commands |
* Enable timestamps on individual commands |
||
* Dates expressed as YY-MM-DD hh:mm:ss |
* Dates expressed as YY-MM-DD hh:mm:ss |
||
− | * Converted copy of the individual timestamps |
+ | * Converted copy of the individual timestamps (requires gawk so enable it only if you have gawk, this is purely cosmetic as timestamps can be converted later if needed) |
* Trap HUP also as invoked bash from mc is apparently interrupted this way |
* Trap HUP also as invoked bash from mc is apparently interrupted this way |
||
+ | <source lang=diff> |
||
− | <pre> |
||
if [ "$PS1" ] ; then # interactive shell |
if [ "$PS1" ] ; then # interactive shell |
||
- export STARTTIME=`date` \ |
- export STARTTIME=`date` \ |
||
Line 195: | Line 196: | ||
fi |
fi |
||
− | </ |
+ | </source> |
+ | And to install the script it is better to insert the following in ~/.bashrc |
||
+ | source ~/.bashrc_history |
||
+ | because e.g. with "vserver xxx enter" the shell is not started in the homedir |
||
+ | <br>['''UPDATE'''] now this "patch" is included in the upstream version, thanks Yaroslav! |
||
+ | <br>Another nice tip from Yaroslav is to define another function in .bashrc_history: |
||
+ | gbha () { grep "$@" ~/.bash_history.archive; } |
||
+ | so you just type "gbha PATTERN" (gbha = grep bash history archive) to find what you need! |
||
+ | ====Examples==== |
||
+ | What did I install last? |
||
+ | gbha "^apt-get install"|tail |
||
+ | When did I modified syslog.conf? |
||
+ | gbha -B2 "syslog.conf" |
||
+ | What did I do that day between 10:00 and 11:59? |
||
+ | gbha -E -A2 "#2006-12-09 1[01]:" |
||
+ | == Conversion d'une string hex en texte == |
||
+ | |||
+ | Input: 48656c6c6f20776f726c640a <br />Output:Hello world |
||
+ | |||
+ | |||
+ | echo "48656c6c6f20776f726c640a" |\ |
||
+ | gawk 'BEGIN{FS=""};{for(i=1;i<=NF;i+=2)printf("%c",strtonum("0x"$i$(i+1)))}' |
||
+ | |||
+ | In Perl: |
||
+ | |||
+ | |||
+ | my $str = "02000501524550454154434f44453a323530"; |
||
+ | print pack('C*', map { hex } unpack('(A2)*', $str)); |
||
+ | ==Compter en hex== |
||
+ | for ((i=0;i<65536;i++)) ; do f=$(printf "%0*X\n" 4 $i); echo $f;done |
||
+ | ==Fix sshd under Cygwin== |
||
+ | Symptom: After IT policy...?? Can connect to sshd but visibly server cannot spawn to user shell |
||
+ | <br>Fix |
||
+ | cygrunsrv -E sshd |
||
+ | cygrunsrv -R sshd |
||
+ | rm -rf /var/log/sshd* /etc/ssh_host* /etc/sshd_config /var/empty /tmp/ssh* |
||
+ | net user cyg_server /delete |
||
+ | net user sshd /delete |
||
+ | sed -i '/^cyg_server/d;/^sshd/d' /etc/passwd |
||
+ | ssh-host-config -y |
||
+ | ssh-user-config |
||
+ | cygrunsrv -S sshd |
||
+ | Note that "-d" debug option of ssh-host-config seems to interfere and installation fails if used. |
||
+ | |||
+ | Still troubleshooting new version... |
||
+ | * delete privileged accounts (net user cyg_server /delete...) |
||
+ | * fix? /usr/share/csih/cygwin-service-installation-helper.sh : |
||
+ | 2990: #if ! passwd -e "${csih_PRIVILEGED_USERNAME}" >/dev/null |
||
+ | 2991- if ! passwd -e "${csih_PRIVILEGED_USERWINNAME}" >/dev/null |
||
+ | * see above, do it manually (ssh-host-config #-y) and change proposed DOMAINNAME+cyg_server privileged account in simpler "cyg" (otherwise apparently it's too long for passwd) |
||
+ | * ? in /etc/fstab add "noacl": |
||
+ | none /cygdrive cygdrive binary,noacl,posix=0,user 0 0 |
||
+ | |||
+ | ==Create quickly an empty file== |
||
+ | Want to create e.g. a big file for a loop filesystem? |
||
+ | <br>dd is way too slow |
||
+ | <br>To allocate space (on filesystems supporting it, FAT doesn't) |
||
+ | fallocate -l 50G mystuff.img |
||
+ | Else, working on FAT: |
||
+ | truncate -s 50G mystuff.img |
||
+ | Then e.g. |
||
+ | /sbin/mkfs.ext3 mystuff.img |
||
+ | mkdir mystuff.mnt |
||
+ | sudo mount -o loop mystuff.img mystuff.mnt |
||
+ | |||
+ | ==DON'T TRY AT HOME== |
||
+ | :(){ :|:& };: |
Latest revision as of 16:56, 24 February 2015
Documentation
- Advanced Bash-Scripting Guide
- http://www.ss64.com/bash/index.html
- http://tille.xalasys.com/training/bash
Sous MC
Shortcuts
- ctrl+o: toggler l'affichage console/mc
- alt+o: même chemin dans l'autre fenêtre
- alt+enter: copie sur la ligne de commande le nom du fichier pointé
- * (num key!): inverse la sélection
- + (num key!): permet de sélectionner selon un filtre, par défaut prend directement tous les fichiers (pas les réps) dans le répertoire courant
- - (num key!): permet de désélectionner avec un filtre
- ctrl+u: undo
- ctrl+l: rafraîchir l'écran
- Bien plus dans le manuel: F1 -> appuyer sur down pour aller sur "contents"; enter -> les keys
Tips
- Pour pouvoir faire des sélections à la souris (gpm ou X) sans que mc ne les interprète, tenir la touche shift enfoncée
- J'aime lancer mes mc root avec un alias qui me met un fond rouge plutot que bleu, l'idée vient de Damn Small Linux mais ici en employant les options mc:
alias smc='sudo -H mc --colors normal=,red:selected=,brightmagenta:marked=,red:markselect=,brightmagenta:directory=,red:executable=,red:link=,red:stalelink=brightcyan,red:device=,red:special=,red:core=,red:input=,green /root'
- mc permet de se connecter via ftp ou ssh, d'ouvrir les tar.gz, tar.bz2, les rpm, les deb, les iso, ... en fait quasi tout ce qui peut être représenté comme un système de fichiers, réel ou virtuel.
- Si il y a un problème avec la touche alt (qui ne fonctionne pas en tant que touche "meta"): F9 -> options -> display bits -> 3eme: uncheck full 8-bits input
Cela mettera use_8th_bit_as_meta=1 dans ~/.mc/ini - Pour d'autres problèmes de ce type, jetez un oeil à cette FAQ
Séquences de couleur ISO 6429 (ANSI)
echo -e "Test \033[31mrouge\033[m" echo -e "Test \033[1;31mrouge vif\033[m" echo -e "Test \033[32mvert\033[m" echo -e "Test \033[1;31mvert vif\033[m" man dir_colors
ESC[rowsA Cursor up ESC[rowsB Cursor down ESC[colsC Cursor right ESC[colsD Cursor left ESC[row;colH Set cursor position (top left is row 1, column 1) ESC[2J Clear screen ESC[K Clear from cursor to end of line ESC[row;colf Set cursor position, same as "H" command ESC[=modeh Set display mode; see table of mode values below ESC[=model Set display mode; see table of mode values below ESC[attr;attr;..m Set display attributes; see table of attribute values below ESC[key;string;..p Substitute "string" for the specified key; see key substitutions section below. ESC[s Save cursor position (may not be nested) ESC[u Restore cursor position after a save
Attribute Description
- 0 All attributes off (normal white on black)
- 1 High intensity (bold)
- 2 Normal intensity
- 4 Underline (usually effective only on monochrome displays)
- 5 Blinking
- 7 Reverse Video
- 8 Invisible
- 30-37 Set the foreground color: 30=Black 31=Red 32=Green 33=Yellow 34=Blue 35=Magenta 36=Cyan 37=White
- 40-47 Set the background color: 40=Black 41=Red 42=Green 43=Yellow 44=Blue 45=Magenta 46=Cyan 47=White
Settings are cumulative, so (for example) to set bright red foreground set all attributes off, then set red, then bold: echo _[0;31;1m.
Display Modes
- 0 Text 40x25 monochrome
- 1 Text 40x25 color
- 2 Text 80x25 monochrome
- 3 Text 80x25 color
- 4 Graphics 320x200 4-color
- 5 Graphics 320x200 4-color
- 6 Graphics 640x200 2-color
- 7 (cursor wrap kludge)
Mode 7 is an unfortunate kludge; Setting mode 7 with an "h" command tells ANSI to wrap text to the next line when it passes the end of a line; setting mode 7 with an "l" (lower-case L) command tells ANSI not to wrap text. For all other modes the "h" and "l" commands are equivalent.
Key Substitutions
The key substitutions ("p") command causes ANSI to substitute the text in "string" when the specified key is pressed. The key code can be a single character in quotes, a numeric ASCII value, or an extended code for a non ASCII key (e.g. function or cursor keys) in the form 0;n, where n is the scan code for the key. The string to be substituted can be a single character or character string in quotes, a numeric ASCII value, or an extended key code.
For a list of numeric ASCII values, see ASCII Tables. For a list of extended key codes see Key Code and Scan Code Tables.
To clear a key substitution, "substitute" the original key for itself.
TAB completion
- Avoid the bell: add "set bell-style visible" to ~/.inputrc (versus audible and none)
- Discover the rules when completing a given command, e.g. acroread: complete|grep acroread
Rules are in /etc/bash_completion and loaded in the environment (see set)
- See http://aplawrence.com/Unix/customtab.html
- Enabling custom completions: shopt -s progcomp
- Registering a custom function to complete command line of e.g. myprog: complete -F _myprog -o dirnames myprog
- Creating the custom function:
_myprog()
{
local curw
COMPREPLY=()
curw=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=($(compgen -A user -- $curw))
return 0
}
Misc
Pay attention when using sudo that $HOME is still configured as yours and you could end up with some user config files owned by root in your own directory.
To avoid that, use "sudo -H" or to make it definitive, use visudo to add to the sudo conf: "Defaults always_set_home"
To convert ASCII Mac file to Unix file:
for file in *; do cat "$file" | tr \\15 \\12 >e;mv e "$file"; done
To convert a filename from uppercase to lowercase
for file in * ; do mv "$file" "$(echo -n $file|tr [[A-Z] [[a-z])" ; done
Boot Disk :
mkbootdisk numero version : voir version dans /lib/modules/2.... ou rdev -h : aide rdev /boot/kernel - < nom du noyau dd if=/boot/linux of=/dev/fd0 bs=8192
Conversion Ext2 -> Ext3
tune2fs -j /dev/hdXX
And don't forget to adapt fstab entry
Devinette
What is the output of this command?
echo one>/tmp/t;(echo two>/dev/stdout)>>/tmp/t;cat /tmp/t
Now, try...
Astonishing, isn't it?!
PS: to get what you expected, try >>/dev/stdout
Apparently when the command is executed, the sub-process is launched with /dev/stdout pointing to its /proc/self/fd/1 but this one is now set to /tmp/t so the sub-shell re-opens the file and overwrites it!
Note that under cygwin/bash, there is no real /dev/stdout and the result is one two
echo one>/tmp/t;m=$(echo two>/dev/stdout);echo $m>>/tmp/t;cat /tmp/t is working as expected, /proc/self/fd/1 of the sub-process is now a pipe to the main process.
So a program is able to detect if its output was redirected or not!
Little scripts
To constitute a dictionary for Scrabble from a french dict:
grep -v [-\'.] /usr/share/dict/french|unaccent ISO-8859-1|sort -u>scrabble-french
Usual prefixes:
cat scrabble-french |cut -c-3|uniq -c|sort -n -r|gawk '$1>1000{print $2}' cat scrabble-french |cut -c-2|uniq -c|sort -n -r|gawk '$1>2000{print $2}'
To find usual suffixes, invert the dictionary:
cat scrabble-french|tr "\n" "."|tac -r -s.|tr "." "\n"|sort>scrabble-suffix
Then find the most common suffixes:
cat scrabble-suffix |cut -c-4|uniq -c|sort -n|gawk '$1>1000{print $2}'|tr "\n" "."|tac -r -s.|tr "." "\n" cat scrabble-suffix |cut -c-3|uniq -c|sort -n|gawk '$1>2000{print $2}'|tr "\n" "."|tac -r -s.|tr "." "\n" cat scrabble-suffix |cut -c-2|uniq -c|sort -n|gawk '$1>2000{print $2}'|tr "\n" "."|tac -r -s.|tr "." "\n" cat scrabble-suffix |cut -c-1|uniq -c|sort -n|gawk '$1>5000{print $2}'|tr "\n" "."|tac -r -s.|tr "." "\n"
History
To enable timestamps in the history, set the env variable (see 'man strftime')
HISTTIMEFORMAT='%F %T '
To convert timestamps from the history file
perl -e 'print scalar localtime(1141863326), "\n"'
To keep the history "forever", here is a nice .bashrc_history script to install
I adapted some stuff:
- Enable timestamps on individual commands
- Dates expressed as YY-MM-DD hh:mm:ss
- Converted copy of the individual timestamps (requires gawk so enable it only if you have gawk, this is purely cosmetic as timestamps can be converted later if needed)
- Trap HUP also as invoked bash from mc is apparently interrupted this way
if [ "$PS1" ] ; then # interactive shell
- export STARTTIME=`date` \
- HISTORYDUMP=0
+ export STARTTIME=`date '+%Y-%m-%d %H:%M:%S'` \
+ HISTORYDUMP=0 \
+ HISTTIMEFORMAT='%F %T '
shopt -s cmdhist histappend
# Next function really stores the history logs. Besides that if you want to store whatever you have so far
# you can call this function and it will save increment from the last call to it.
archive_history()
{
TFILE=${HISTFILE}.$$.temp
- CURTIME=`date`
+ CURTIME=`date '+%Y-%m-%d %H:%M:%S'`
CURTTY=`tty`
#STAMP
HISTORYDUMP=$(($HISTORYDUMP+1))
# Title
echo "#$USER@${HOSTNAME} [ ${STARTTIME} - ${CURTIME} ]:$HISTORYDUMP ($CURTTY) ----" >| $TFILE
# Fresh tasty history
history -a ${TFILE}
# Append it to the archive
- cat ${TFILE} >> ${HISTFILE}.archive
+ #cat ${TFILE} >> ${HISTFILE}.archive
+ # But we add a converted version of the timestamp
+ gawk '/^#[0-9]+$/{print strftime("#%F %T ", gensub(/#/,"","g")) }//' ${TFILE} >> ${HISTFILE}.archive
# Adjust history file itself
# of cause we need to dump to some temp file and then rename... he heh
cat ${HISTFILE} ${TFILE} | tail -${HISTSIZE} >| ${HISTFILE}.$$
mv -f ${HISTFILE}.$$ ${HISTFILE}
# clean up after yourself - to be absessive remove the other tmp file as well -
# - might happen if there were no permission to move it at above point
rm -rf ${TFILE} ${HISTFILE}.$$
}
- trap 'archive_history' EXIT
+ trap 'archive_history' EXIT HUP
unset IGNOREEOF
fi
And to install the script it is better to insert the following in ~/.bashrc
source ~/.bashrc_history
because e.g. with "vserver xxx enter" the shell is not started in the homedir
[UPDATE] now this "patch" is included in the upstream version, thanks Yaroslav!
Another nice tip from Yaroslav is to define another function in .bashrc_history:
gbha () { grep "$@" ~/.bash_history.archive; }
so you just type "gbha PATTERN" (gbha = grep bash history archive) to find what you need!
Examples
What did I install last?
gbha "^apt-get install"|tail
When did I modified syslog.conf?
gbha -B2 "syslog.conf"
What did I do that day between 10:00 and 11:59?
gbha -E -A2 "#2006-12-09 1[01]:"
Conversion d'une string hex en texte
Input: 48656c6c6f20776f726c640a
Output:Hello world
echo "48656c6c6f20776f726c640a" |\ gawk 'BEGIN{FS=""};{for(i=1;i<=NF;i+=2)printf("%c",strtonum("0x"$i$(i+1)))}'
In Perl:
my $str = "02000501524550454154434f44453a323530"; print pack('C*', map { hex } unpack('(A2)*', $str));
Compter en hex
for ((i=0;i<65536;i++)) ; do f=$(printf "%0*X\n" 4 $i); echo $f;done
Fix sshd under Cygwin
Symptom: After IT policy...?? Can connect to sshd but visibly server cannot spawn to user shell
Fix
cygrunsrv -E sshd cygrunsrv -R sshd rm -rf /var/log/sshd* /etc/ssh_host* /etc/sshd_config /var/empty /tmp/ssh* net user cyg_server /delete net user sshd /delete sed -i '/^cyg_server/d;/^sshd/d' /etc/passwd ssh-host-config -y ssh-user-config cygrunsrv -S sshd
Note that "-d" debug option of ssh-host-config seems to interfere and installation fails if used.
Still troubleshooting new version...
- delete privileged accounts (net user cyg_server /delete...)
- fix? /usr/share/csih/cygwin-service-installation-helper.sh :
2990: #if ! passwd -e "${csih_PRIVILEGED_USERNAME}" >/dev/null 2991- if ! passwd -e "${csih_PRIVILEGED_USERWINNAME}" >/dev/null
- see above, do it manually (ssh-host-config #-y) and change proposed DOMAINNAME+cyg_server privileged account in simpler "cyg" (otherwise apparently it's too long for passwd)
- ? in /etc/fstab add "noacl":
none /cygdrive cygdrive binary,noacl,posix=0,user 0 0
Create quickly an empty file
Want to create e.g. a big file for a loop filesystem?
dd is way too slow
To allocate space (on filesystems supporting it, FAT doesn't)
fallocate -l 50G mystuff.img
Else, working on FAT:
truncate -s 50G mystuff.img
Then e.g.
/sbin/mkfs.ext3 mystuff.img mkdir mystuff.mnt sudo mount -o loop mystuff.img mystuff.mnt
DON'T TRY AT HOME
:(){ :|:& };: