# Linux algemeen & CLI

# Linux general

- [rsync root volume to new harddisk](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/rsync-root-volume-to-new-harddisk)
- [enable wifi after suspend-resume](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/enable-wifi-after-suspend-resume)
- [edit PDF metadata](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/edit-pdf-metadata)
- [change root's theme](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/change-roots-theme)
- [swap file on BTRFS](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/swap-file-on-btrfs)
- [chrome options](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/chrome-options)
- [fix bash history](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/fix-bash-history)
- [How to send email from command line in fixed font](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/how-to-send-email-from-command-line-in-fixed-font)
- [update etherpad](https://www.reeltoreel.nl/knowledgebase/books/archief/page/update-etherpad)
- [rootvg won't resize](https://www.reeltoreel.nl/knowledgebase/books/archief/page/rootvg-wont-resize)
- [x11 forwarding for sudo users](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/x11-forwarding-for-sudo-users)
- [chromecast op linux](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/chromecast-op-linux)
- [AIX cheatsheet](https://www.reeltoreel.nl/knowledgebase/books/archief/page/aix-cheatsheet)
- [linux algemeen](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/linux-algemeen)
- [SOX audio examples](https://www.reeltoreel.nl/knowledgebase/books/audio/page/sox-audio-examples)
- [sort installed rpms by size](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/sort-installed-rpms-by-size)
- [view progress of dd](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/view-progress-of-dd)
- [dealing with spaces in filenames](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/dealing-with-spaces-in-filenames)
- [POSTFIX](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/postfix)
- [How to backup your disk with dd](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/how-to-backup-your-disk-with-dd)
- [How to make a webcam page with Apache on Linux](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/how-to-make-a-webcam-page-with-apache-on-linux)
- [How to make Audacity work with ALSA](https://www.reeltoreel.nl/knowledgebase/books/audio/page/how-to-make-audacity-work-with-alsa)
- [Reinstalling GRUB after Windows install](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/reinstalling-grub-after-windows-install)
- [Make .par files work in KDE](https://www.reeltoreel.nl/knowledgebase/books/archief/page/make-par-files-work-in-kde)
- [Keyboard setting for diacritical characters](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/keyboard-setting-for-diacritical-characters)
- [How to make a .iso file from your CD or DVD](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/how-to-make-a-iso-file-from-your-cd-or-dvd)
- [How to find duplicate files BY CONTENT!!](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/how-to-find-duplicate-files-by-content)
- [How to clone or copy your harddisk over the network](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/how-to-clone-or-copy-your-harddisk-over-the-network)
- [How to connect to server on strange port, or when you're behind a firewall](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/how-to-connect-to-server-on-strange-port-or-when-youre-behind-a-firewall)
- [How to find information about a host or webserver](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/how-to-find-information-about-a-host-or-webserver)
- [How to make a virtualBox window seamless](https://www.reeltoreel.nl/knowledgebase/books/archief/page/how-to-make-a-virtualbox-window-seamless)
- [Using bridged networking in VirtualBox](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/using-bridged-networking-in-virtualbox)
- [Mounting remote directories using FUSE and sshfs on openSUSE](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/mounting-remote-directories-using-fuse-and-sshfs-on-opensuse)
- [Using x2x to connect two computers and their screens with one mouse and keyboard](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/using-x2x-to-connect-two-computers-and-their-screens-with-one-mouse-and-keyboard)
- [Convert an AVCHD / MTS file to MP4 using ffmpeg](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/convert-an-avchd-mts-file-to-mp4-using-ffmpeg)
- [How to restore MBR on harddisk](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/how-to-restore-mbr-on-harddisk)
- [How to automatically log in to remote ssh servers using public/private keypair](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/how-to-automatically-log-in-to-remote-ssh-servers-using-publicprivate-keypair)
- [How to make an encrypted directory](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/how-to-make-an-encrypted-directory)
- [How to send mail via telnet to a server using SMTP commands](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/how-to-send-mail-via-telnet-to-a-server-using-smtp-commands)
- [How to test network speed](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/how-to-test-network-speed)
- [How to convert an existing ext3 filesystem to ext4](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/how-to-convert-an-existing-ext3-filesystem-to-ext4)
- [How to make a dump of a website](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/how-to-make-a-dump-of-a-website)
- [Linux performance monitoring](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/linux-performance-monitoring)
- [How to make a shell fork bomb](https://www.reeltoreel.nl/knowledgebase/books/archief/page/how-to-make-a-shell-fork-bomb)
- [How to resque a hanging linux](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/how-to-resque-a-hanging-linux)
- [Script to check and restart a process](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/script-to-check-and-restart-a-process)
- [Enlarge disks by removing reserve space on ext2/3/4](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/enlarge-disks-by-removing-reserve-space-on-ext234)
- [SSH filesystem](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/ssh-filesystem)
- [Using GRUB to boot multiple operating systems, the correct way](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/using-grub-to-boot-multiple-operating-systems-the-correct-way)
- [iptables for dummies](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/iptables-for-dummies)
- [Convert .pcd (PhotoCD) files](https://www.reeltoreel.nl/knowledgebase/books/archief/page/convert-pcd-photocd-files)

# Image manipulation (The Gimp, DigiKam)

**How to make a portion of an image transparent using The Gimp**

Sometimes you want to make a certain portion of an image transparent.

This is for instance to make an image look good, placed on a background on a web page.

Remember that only .GIF and .PNG support this feature, NOT .JPG!! This can easily be done using The Gimp.

`  1. Open your image in the Gimp. File -> Open.`  
`  2. Right click the image and go to LAYERS then ADD ALPHA CHANNEL. This is the transparency layer.`  
`  3. Right click on the image again and go to SELECT and then BY COLOR.`  
`  4. Now click on the color in the image you want to be transparent. These colors will now show up outlined.`  
`  5. Right click on the image again and go to EDIT and then down to CLEAR. `  
`     This should now erase the outlined color you just picked from the image and the "transparent gimp checkerbox" should show through. `  
`     This is the Gimps way of showing you that section is now transparent.`  
`  6. Right click on the image and choose SAVE AS and make sure to save as a GIF file if you want the transparency to work on the web. `  
`     Select CONVERT TO INDEXED if necessary. It is also possible to SAVE AS... PNG`  
`  7. That's it!`

# Linux and hardware

- [test harddisk for bad blocks](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/test-harddisk-for-bad-blocks)
- [set cpu performance](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/set-cpu-performance)
- [determine which vga driver is in use](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/determine-which-vga-driver-is-in-use)
- [rsync root volume](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/rsync-root-volume)
- [rescan SCSI bus](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/rescan-scsi-bus)
- [disable cpu core for light work](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/disable-cpu-core-for-light-work)
- [detect webcam properties](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/detect-webcam-properties)
- [bogomips](https://www.reeltoreel.nl/knowledgebase/books/archief/page/bogomips)
- [RAID](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/raid)
- [Garmin Forerunner 305, linux and Garmin Connect](https://www.reeltoreel.nl/knowledgebase/books/archief/page/garmin-forerunner-305-linux-and-garmin-connect)
- [Speedtouch commands](https://www.reeltoreel.nl/knowledgebase/books/archief/page/speedtouch-commands)
- [enable suspend-to-ram on notebooks with ATI card](https://www.reeltoreel.nl/knowledgebase/books/archief/page/enable-suspend-to-ram-on-notebooks-with-ati-card)
- [enable harddisk spin-down / sleep mode / standby](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/enable-harddisk-spin-down-sleep-mode-standby)
- [enable monitoring of MD (software RAID) devices](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/enable-monitoring-of-md-software-raid-devices)
- [disable hardware polling for CD-drives](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/disable-hardware-polling-for-cd-drives)
- [Linux Software RAID: growing filesystems and adding disks](Linux_Software_RAID:_growing_filesystems_and_adding_disks "wikilink")
- [ATI graphic chipset overview](https://www.reeltoreel.nl/knowledgebase/books/archief/page/ati-graphic-chipset-overview)
- [Burning CD/DVD from CLI with wodim](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/burning-cddvd-from-cli-with-wodim)
- [Verhuis een linux systeem naar nieuwe hardware](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/verhuis-een-linux-systeem-naar-nieuwe-hardware)
- [Install Linux on an SSD](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/install-linux-on-an-ssd)
- [perform bechmarks on the filesystem](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/perform-bechmarks-on-the-filesystem)
- [Screenresolutions, dimensions and DPI](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/screenresolutions-dimensions-and-dpi)

# Watch

- Herrie [http://www.herrie.info](http://www.herrie.info)commandline mp3 player/jukebox
- Thunder &amp; Lightning 3D war simulator [http://tnlgame.net](http://tnlgame.net)
- WeedIt File duplicate scanner [http://adm1n.cjb.net/cw](http://adm1n.cjb.net/cw)
- Bacula [http://www.bacula.org](http://www.bacula.org)
- MyRPM Create RPMs without fuss [http://code.google.com/p/myrpm](http://code.google.com/p/myrpm)
- RockBox Open source firmware replacement for many popular MP3 players
- [http://bluemarine.tidalwave.it/](http://bluemarine.tidalwave.it/)An open source application for the digital photo workflow
- [http://www.linux.com/articles/57222](http://www.linux.com/articles/57222)tesseract en other OCR meuk
- [http://groundstate.ca/ocr](http://groundstate.ca/ocr)ocropus
- [http://www.openfiler.com](http://www.openfiler.com)opensource NAS
- [http://www.andlinux.org/](http://www.andlinux.org/) run linux from within wondows
- [http://www.ossec.net/](http://www.ossec.net/) OSSEC is an Open Source Host-based Intrusion Detection System. It performs log analysis, file integrity checking, policy monitoring, rootkit detection, real-time alerting and active response
- [http://www.jokosher.org/](http://www.jokosher.org/)jokosher audio editor
- Zenmap graphical interface for nmap
- slowloris apache killler
- Unetbootin install any os on usb stick
- [http://pianoteq.com](http://pianoteq.com) piano synthesizer
- [http://luma.sourceforge.net](http://luma.sourceforge.net) -&gt; graphical LDAP browser
- [http://www.php-web-statistik.de/index-english.html](http://www.php-web-statistik.de/index-english.html "wikilink")php webstat
- [http://download.bitdefender.com/SMB/Workstation\_Security\_and\_Management/BitDefender\_Antivirus\_Scanner\_for\_Unices/Unix/Current/EN\_FR\_BR\_RO/Linux/ bitdefender antivirus scanner](http://download.bitdefender.com/SMB/Workstation_Security_and_Management/BitDefender_Antivirus_Scanner_for_Unices/Unix/Current/EN_FR_BR_RO/Linux/_bitdefender_antivirus_scanner "wikilink")
- [http://kde-apps.org/content/show.php/Hydrogen?content=14152 Hydrogen KDE Sound Application](http://kde-apps.org/content/show.php/Hydrogen?content=14152_Hydrogen_KDE_Sound_Application "wikilink")
- [http://www.jolicloud.com jolicloud, netbook OS](http://www.jolicloud.com_jolicloud,_netbook_OS "wikilink")
- [http://www.openvas.org openvas, fork from nessus](http://www.openvas.org_openvas,_fork_from_nessus "wikilink")
- [http://www.roomle.com roomle, online woninginrichting](http://www.roomle.com_roomle,_online_woninginrichting "wikilink")
- [gbrainy brain trainer](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/gbrainy-brain-trainer)
- [typolight lightweight CMS](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/typolight-lightweight-cms)

# How to find duplicate files BY CONTENT!!

Today in IRC suseROCKS needed to find all duplicate files in a directory by their content, not by their file name, so we whipped up this fancy little 1 liner bash script to do the trick:

`find . -type f -exec md5sum '{}' \; | sort | awk 'dup[$1]++{print $2}'`

EDIT:

As Andreas suggested, using xargs instead of -exec is much faster, here is the updated command:

`find . -type f -print0 | xargs -0 md5sum | sort | awk 'dup[$1]++{print $2}'`

# How to clone or copy your harddisk over the network

## Method 1 (tested!)

On the bron/zender/source:

`#dd if=/dev/sda | gzip -c | netcat -l -q 0 -p 2222 `

On the ontvanger/doel/target:

`#netcat `<ip server="" van="">` 2222 | gzip -cd | dd of=/dev/sda`</ip>

This way we get a throughput of 14,1 MB/s, 160 GB in 11543 seconds (3,2 hour)

## Methode 2 (niet getest!)

How do I use netcat to copy hard disk image?

Our sample setup

`HostA // 192.168.1.1`  
`          sda`  
`       NETWORK`  
`          sdb`  
`HostB // 192.168.1.2`

Your task is copy HostA /dev/sda to HostB's /dev/sdb using netcat command. First login as root user Command to type on hostB (receiving end ~ write image mode)

You need to open port on hostB using netcat, enter :

`# netcat -p 2222 -l |bzip2 -d | dd of=/dev/sdb`

Where,

`   * -p 2222 : Specifies the source port nc should use, subject to privilege restrictions and availability.   Make sure port 2222 is not used by another process.`  
`   * -l : Used to specify that nc should listen for an incoming connection rather than initiate a connection to a remote host.`  
`   * bzip2 -d : Compresses image using the Burrows-Wheeler block sorting text compression algorithm, and Huffman coding. This will speed up network transfer ( -d : force decompression mode)`  
`   * dd of=/dev/sda : /dev/sda is your hard disk. You can also specify partition such as /dev/sda1`

Command to type on hostA (send data over a network ~ read image mode)

Now all you have to do is start copying image. Again login as root and enter:

`# bzip2 -c /dev/sda | netcat hostA 2222`

OR use IP address:

`# bzip2 -c /dev/sda | netcat 192.168.1.1 2222`

This process takes its own time. A note about latest netcat version 1.84-10 and above

If you are using latest nc / netcat version above syntax will generate an error. It is an error to use -l option in conjunction with the -p, -s, or -z options. Additionally, any timeouts specified with the -w option are ignored. So use nc command as follows.

On hostA, enter:

`# nc -l 2222 > /dev/sdb`

On hostB, enter:

`# nc hostA 2222< /dev/sda`

OR

`# nc 192.168.1.1 2222< /dev/sda`

Using a second machine (hostB), connect to the listening nc process at 2222 (hostA), feeding it the file (/dev/sda)which is to be transferred. You can use bzip2 as follows. On hostA, enter:

`# nc -l 2222 | bzip2 -d > /dev/sdb`

On hostB, enter:

`# bzip2 -c /dev/sda | nc 192.168.1.1 2222`

# How to find information about a host or webserver

`nmap -sV -P0 -O [server]`

# Linux commandline tips

# Bash tips

```
^r      Reverse search the command history
^a  Return to the start of the command you're typing
^e  Go to the end of the command you're typing
^u  Cut everything before the cursor to a special clipboard
^k  Cut everything after the cursor to a special clipboard
^y  Paste from the special clipboard that Ctrl + u and Ctrl + k save their data to
^t  Swap the two characters before the cursor (you can actually use this to transport a character from the left to the right, try it!)
^w  Delete the word / argument left of the cursor
^l  Clear the screen

history    lists command history
!61        executes command on line 61

ls -l /etc/passwd
stat !$             no need to repeat argument on second line

man -k <keyword>     searches in all man pages for <keyword>

ls *.mp3 | xargs rm
ls *.mp3 | xargs -i cp {} /home/bla
ls *.mp3 -d  -> stays in current dir and doesn't enter mp3/
```

- start a restricted shell (no cd, etc) to test programs

`# bash -r`

- start shell with options

`# bash -O [modification]`  
`autocd -> use the argument as cd command`  
`cd-spell -> corrects dir names`  
`dirspell -> corrects dir names in file completion`  
`no-caseglob -> case insensitive`

---

to run commands:

`# command1 && command2`

logical AND :: run command1, if ok then run command2

`# command1 || command2`

logical OR :: run command2 only if command1 fails

# cp

`cp -rv `

gives feedback

`cp -p`

preserves original date/time

# dd

use blocks of 64k and report every 10Mb:

`dd if=/dev/hda | buffer -s 64k -S 10m > image`

or, from other console:

`kill -SIGUSR1 $(pidof dd)`

# df

`df -type=ext3,ReiserFS`  
`df -H human readable`

# find

find all files in your homedir modified or created today

`find ~ -type f -mtime 0`

case insentive search

`find . -iname "*mp3"`

find files and directories in yor homedir not created by you

`find ~ ! -user ${USER}`

and fix this

`find ~ ! -user ${USER} -exec sudo chown ${USER}:"{}" \;`

find duplicates PvdM

`find . -type f -exec md5sum '{}' ';' | sort | uniq --all-repeated=separate -w 15`

# free

`free -m -> megabytes`  
`free -t -> totals`  
`free -s[seconds] -> update interval`

watch the line with +/- buffers: **free** indicates memory that can be freed instantaniously **used** is all memory being used

# grep

`grep -A2 bla greps 2 lines after`  
`grep -B3 bla greps 3 lines before`

# history

`# history -d [postition] -> remove specific command`  
`# history -c -> clear entire history`

# iotop

monitors io proces

`iotop -o makes output more readable by showing only processes causing io right now `  
`iotop -d10 refresh interval`  
`iotop -o -b -d10 -n30 > io.txt batch mode: write io status 30 times to file at 10s interval`

# iperf

`iperf -s -w128k run server for performance benchmark`  
`iperf -c `<serveraddress>` -w128k -t30 -r run client`  
`iperf -c `<serveraddress>` -w128k -t30 -d run client in two directions, full duplex`</serveraddress></serveraddress>

# kill

kill -l shows instructions

` 1  SIGHUP   restart immediately after terminating, or triggers reconfiguration of background service`  
` 2  SIGINT   Ctrl+c from the keyboard, terminate!`  
` 3  SIGQUIT  Ctrl+\ from the keyboard, terminate with coredump`  
` 9  SIGKILL  force terminate, extreme signal that can't ignored`  
`11  SIGSEGV  program attempted an invalid memory reference, terminate with coredump`  
`15  SIGTERM  request to terminate and cleanup`  
`19  SIGSTOP  interrupts the process until you enter SIGCONT to continue`

`kill -19 9102 10234  stops several processes`  
`killall -19 ssh      sends all ssh connections to sleep`  
`killall -19 -i ssh   interactive mode (recommended)`

# lsof

`lsof list open files`  
`lsof -i :22 list all ssh connections (same :ssh)`  
`lsof -i@10.0.0.1 list all connections from 10.0.0.1`  
`lsof -i@amsterdam.nl list all connections from domain`  
`lsof -u username list all open files from username`  
`lsof -c bash list open files related to bash`  
`lsof -c /log/ list all open files from all processes containing log`

# lspci

`lspci -v `  
`lspci -vv`  
`lspci -vvv`  
`lspci -nn -> show names & numerical `  
`lspci -k -> show kernel modules associated with the device`

# more or less

`+`<number>` number of line from which to start displaying`  
`z `<number>`  number of lines to jump forward`  
`y `<number>` number of lines to jump back`  
`-I ignore case when searching`  
`-V underline tabs, line endings`  
`/`<ctrl-k>` highlights all ocurrences of search`</ctrl-k></number></number></number>

# pgrep

`pgrep ssh lists all ssh processes`  
`pgrep -l ssh shows names`  
`pgrep -f  shows full commandline`  
`pgrep -u show user`

# ping

`ping 0 -> pings localhost`  
`ping c 5 nu.nl -> pings 5 times`  
`ping -f host -> floods the host`  
`ping -a IP -> gives audible beep Note: It can give beep only from terminal number 1 through 7 and gnome-terminal ( It will not work in console ).`  
`ping -q ip -> show only summary`  
`ping -s 100 -> change packet size`  
`Pressing CTRL+| (Control key followed by pipe symbol) for the shows the summary in between, and continues with it packet sending and receiving process.`  
`ping hop1 hop2 hop3 .. hopN destination`  
`ping -R 192.168.1.63 -> Record and print route of how ECHO_REQUEST sent and ECHO_REPLY received`

# pkill

understands the same options as pgrep

`pkill -19 ssh`  
`pkill -19 -u joop stop joop's processes`

# ps

show how long a process is running

`ps -o pid,etime,cmd `pidof amarok``

show memory usage per process

`ps -e -orss=,args= | sort -b -k1,1n | pr -TW$COLUMNS`

# pstree

`pstree -a shows processes tree structure with program's parameters`  
`pstree -h highlights own process `  
`pstree -H `<id>` highlights process id`  
`pstree -u shows user`</id>

# stat

shows status of file

`stat /etc/passwd   `  
`stat -c "%x %n" /etc/passwd      formatted to show time`

# swapon

`swapon -s see size and usage`

# tail or head

`--retry keep monitoring the file `  
`-s seconds how often monitoring retry`  
`-pid `<pid>` stops tail from running if PID stops running`</pid>

# tar

`tar zxf `<file>` -> extracts file`</file>

# top

```
PID     programma id
USER    gebruiker
PR      prioriteit van de taak
NI      nice value
VIRT    virtuele geheugen gebruik
RES     fysieke geheugen gebruik
SHR     deel v/h gebeugen dat mogelijk met andere taken wordt gedeeld
%CPU    percentage processorgebruik
%MEM    percentage geheugengebruik
TIME+   de tijd dat de taak op de cpu heeft gedraaid
COMMAND de naam van de taak
```

keys: z: enable color mode. x: show sorted column in different color &lt; &gt;: change sorted column u \[user\]: show only users processes d: delay in sec

show only user user

`#top -u user`

# zombies

`ps aux | grep defunct`

# AutoYast

create autoyast file through icon in Yast2-&gt;autoyast

`www.suse.de/~ug (Uwe Gansert)`

# Midnight Commander (MC)

The standard colorpallette is incredibly hard to read in certain terminals, like yakuake.

For readable colors (mostly black and green), enter in your ~/.mc/ini file the following line:

`[Colors]`  
`base_color=lightgray,green:normal=green,default:selected=white,gray:marked=yellow,default:markselect=yellow,gray:directory=blue,default:executable=brightgreen,default:link=cyan,default:device=brightmagenta,default:special=lightgray,default:errors=red,default:reverse=green,default:gauge=green,default:input=white,gray:dnormal=green,gray:dfocus=brightgreen,gray:dhotnormal=cyan,gray:dhotfocus=brightcyan,gray:menu=green,default:menuhot=cyan,default:menusel=green,gray:menuhotsel=cyan,default:helpnormal=cyan,default:editnormal=green,default:editbold=blue,default:editmarked=gray,blue:stalelink=red,default`

# tune kernelparameters

stored in /proc/sys/ gone after reboot

sysctl is a service that reads sysctl.conf during boot and read parameters from there -&gt; makes it permanent

`# ulimit -a`

givesinfo about system resources limitations

# Using x2x to connect two computers and their screens with one mouse and keyboard

Let's say you have 2 computers:

`cpu1: 10.0.0.1`  
`cpu2: 10.0.0.2`

Let's say cpu1's screen is left to cpu2's screen.

Let's say you want to control cpu1 from cpu2.

<s>Let's assume both computers have the same username.</s>

1. install x2x on cpu1
2. enter on cpu2

`ssh -X user@cpu1 'x2x -west -to :0'`

and leave terminal open.

And that's it!

# Script to check and restart a process

<div class="sourceCode" id="bkmrk-%23%21%2Fbin%2Fbash-%23-------">```
<span id="bkmrk-"><a aria-hidden="true" href="#bkmrk-" tabindex="-1"></a></span>
<span id="bkmrk-%23%21%2Fbin%2Fbash"><a aria-hidden="true" href="#bkmrk-%23%21%2Fbin%2Fbash" tabindex="-1"></a><span class="co">#!/bin/bash</span></span>
<span id="bkmrk-%23-------------------"><a aria-hidden="true" href="#bkmrk-%23-------------------" tabindex="-1"></a><span class="co"># -------------------------------------------------------------------------</span></span>
<span id="bkmrk-%23-copyright-%28c%29-2003"><a aria-hidden="true" href="#bkmrk-%23-copyright-%28c%29-2003" tabindex="-1"></a><span class="co"># Copyright (c) 2003 nixCraft project <http://cyberciti.biz/fb/></span></span>
<span id="bkmrk-%23-this-script-is-lic"><a aria-hidden="true" href="#bkmrk-%23-this-script-is-lic" tabindex="-1"></a><span class="co"># This script is licensed under GNU GPL version 2.0 or above</span></span>
<span id="bkmrk-%23--------------------1"><a aria-hidden="true" href="#bkmrk-%23--------------------1" tabindex="-1"></a><span class="co"># -------------------------------------------------------------------------</span></span>
<span id="bkmrk-%23-this-script-is-par"><a aria-hidden="true" href="#bkmrk-%23-this-script-is-par" tabindex="-1"></a><span class="co"># This script is part of nixCraft shell script http://en.wikipedia.org/wiki/Shell_script collection (NSSC)</span></span>
<span id="bkmrk-%23-visit-http%3A%2F%2Fbash."><a aria-hidden="true" href="#bkmrk-%23-visit-http%3A%2F%2Fbash." tabindex="-1"></a><span class="co"># Visit http://bash.cyberciti.biz/ for more information.</span></span>
<span id="bkmrk-%23-copyright-%28c%29-2010"><a aria-hidden="true" href="#bkmrk-%23-copyright-%28c%29-2010" tabindex="-1"></a><span class="co"># Copyright (c) 2010 CyberOrg Info. Modification to watch any process/service </span></span>
<span id="bkmrk-%23--------------------2"><a aria-hidden="true" href="#bkmrk-%23--------------------2" tabindex="-1"></a><span class="co"># -------------------------------------------------------------------------</span></span>
<span id="bkmrk-restart%3D%22%2Fetc%2Finit.d"><a aria-hidden="true" href="#bkmrk-restart%3D%22%2Fetc%2Finit.d" tabindex="-1"></a><span class="va">RESTART</span><span class="op">=</span><span class="st">"/etc/init.d/sshd restart"</span></span>
<span id="bkmrk-pgrep%3D%22%2Fusr%2Fbin%2Fpgre"><a aria-hidden="true" href="#bkmrk-pgrep%3D%22%2Fusr%2Fbin%2Fpgre" tabindex="-1"></a><span class="va">PGREP</span><span class="op">=</span><span class="st">"/usr/bin/pgrep"</span></span>
<span id="bkmrk-processtowatch%3D%22sshd"><a aria-hidden="true" href="#bkmrk-processtowatch%3D%22sshd" tabindex="-1"></a><span class="va">processtowatch</span><span class="op">=</span><span class="st">"sshd"</span></span>
<span id="bkmrk-x%3D1"><a aria-hidden="true" href="#bkmrk-x%3D1" tabindex="-1"></a><span class="va">x</span><span class="op">=</span>1</span>
<span id="bkmrk-while-%5B-%24x-%3D-1-%5D%3B"><a aria-hidden="true" href="#bkmrk-while-%5B-%24x-%3D-1-%5D%3B" tabindex="-1"></a><span class="cf">while</span> <span class="bu">[</span> <span class="va">$x</span> <span class="ot">=</span> 1 <span class="bu">]</span><span class="kw">;</span></span>
<span id="bkmrk-do"><a aria-hidden="true" href="#bkmrk-do" tabindex="-1"></a><span class="cf">do</span> </span>
<span id="bkmrk-%23-find-pid"><a aria-hidden="true" href="#bkmrk-%23-find-pid" tabindex="-1"></a>    <span class="co"># find pid</span></span>
<span id="bkmrk-%24pgrep-%24%7Bprocesstowa"><a aria-hidden="true" href="#bkmrk-%24pgrep-%24%7Bprocesstowa" tabindex="-1"></a>    <span class="va">$PGREP</span> <span class="va">${processtowatch}</span></span>
<span id="bkmrk-if-%5B-%24%3F--ne-0-%5D"><a aria-hidden="true" href="#bkmrk-if-%5B-%24%3F--ne-0-%5D" tabindex="-1"></a>    <span class="cf">if</span> <span class="bu">[</span> <span class="va">$?</span> <span class="ot">-ne</span> 0 <span class="bu">]</span></span>
<span id="bkmrk-then"><a aria-hidden="true" href="#bkmrk-then" tabindex="-1"></a>    <span class="cf">then</span></span>
<span id="bkmrk-echo-%22%60date%60-%3A-%24proc"><a aria-hidden="true" href="#bkmrk-echo-%22%60date%60-%3A-%24proc" tabindex="-1"></a>        <span class="bu">echo</span> <span class="st">"</span><span class="kw">`</span><span class="fu">date</span><span class="kw">`</span><span class="st"> : </span><span class="va">$processtowatch</span><span class="st"> went down, restarting"</span> <span class="op">>></span> /var/log/restart.log</span>
<span id="bkmrk-%24restart"><a aria-hidden="true" href="#bkmrk-%24restart" tabindex="-1"></a>        <span class="va">$RESTART</span></span>
<span id="bkmrk-fi"><a aria-hidden="true" href="#bkmrk-fi" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="bkmrk-sleep-30"><a aria-hidden="true" href="#bkmrk-sleep-30" tabindex="-1"></a>    <span class="fu">sleep</span> 30</span>
<span id="bkmrk-done"><a aria-hidden="true" href="#bkmrk-done" tabindex="-1"></a><span class="cf">done</span></span>
```

</div>

# Vi tips

# vi editor tips

## Keys

<table id="bkmrk-key%28s%29%3A-movement%3A-0-"><tbody><tr><td style="background-color:#99ccff;border:0.0007in solid #000000;padding:0.0382in;">***Key*(s):**

</td><td style="background-color:#99ccff;border:0.0007in solid #000000;padding:0.0382in;">***Movement*:**

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">0 (zero)

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">1<sup>st</sup>column on the line

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">^

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">1<sup>st</sup>**non-blanc**char on line

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">$

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Last char on line

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">g\_

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Last **non-blanc** char on line

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">w

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Next word

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">W

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Next word and **skip** interpunction

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">e

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">End of current word

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">E

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">End of current word **incl** .interpunction

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">b

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Begin of current word

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">B

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Begin of current word **incl**. interpuction

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">ge

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">End of previous word

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">gE

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">End of previous word and **skip** interpunction

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">O

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Insert new line and switch to insert mode

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;"></td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;"></td></tr><tr><td style="background-color:#99ccff;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">***Key*(s):**

</td><td style="background-color:#99ccff;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">***Action*:**

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">x

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Delete char **under** cursor

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">X

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Delete char **before** cursor

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">r

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Replace char under cursor with next typed char

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;"></td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;"></td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">d

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Delete chars until position of next command

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">dd

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Delete line

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">y

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Copy text until position of next command

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">yy

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Copy line

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">p

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Paste text **after**cursor

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">P

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Paste text **before**cursor

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;"></td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;"></td></tr><tr><td style="background-color:#99ccff;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">***Key(s):***

</td><td style="background-color:#99ccff;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">***Selection:***

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">V

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Start selecting block of text

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">x

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Cut block of text

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">c

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Copy block of text

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">iw

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Word

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">aw

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Word **incl** spaces

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">is

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Sentence

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">as

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Sentence **incl** spaces

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">ip

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Paragraph

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">ap

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Paragraph **incl** spaces and **empty** lines

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">i(

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Block between brackets

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">a(

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Block **incl** brackets

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">i&lt;

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Block between &lt; &gt;

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">a&lt;

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Block **incl** &lt; &gt;

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">i{

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Block between { }

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">a{

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Block **incl** { }

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">i”

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Block between “ “

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">a”

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Block **incl**“ “

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">i`

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Block between ` `

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">a`

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Block **incl**` `

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;"></td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;"></td></tr><tr><td style="background-color:#99ccff;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">***Search:***

</td><td style="background-color:#99ccff;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">***Action:***

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">/text

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Search for text starting at cursor

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">n

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Find next

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">N

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Find previous

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">//

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Repeat last search

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">\*

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Search forward for word currently under cursor

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">\#

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Search backwards for word currently under cursor

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;"></td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;"></td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">:set hlsearch

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Highlights all matches

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">:set nohlsearch

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Disable ^

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">:nohl

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Don't show highlights from last search

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">:set incsearch

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Enables incremental search

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;">:set noincsearch

</td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;">Disables ^

</td></tr><tr><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;"></td><td style="border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;"></td></tr></tbody></table>

u undo

cut multiple lines: ###yy

delete rest of line from cursor: SHIFT-d

## To open multiple files on a window

- Horizontal split

`vi -o file-one file-two`

- Vertical split

`vi -O file-one file-two`

- Switch between the panes you are using.

`     CTRL + W + Left key to activate left windows`  
`     CTRL + W + Right key to activate right windows`  
`     CTRL + W + Up key> to activate to windows above current one`  
`     CTRL + W + Down key> to activate to windows down current one`

- Split Open one file at a time

`vi file-one`

- To open the second file, go to the command mode (Esc)

`:new file-two`

OR

`:split file-two`

- to split vertically

`:vsplit`

- Typ 'CTRL-w w' to switch between the windows
- Open new file:

`:e newfile`

### Tabs

To open Vi with multiple tabs open:

`vi -p /var/log/*.log`

- switch between tabs with *gt*
- open new tab

`:tabnew`  
`or`  
`:tabe file`

to open new file in new tab

## Search and Replace

Go in command mode and type:

Replace First occurence of string

`:%s/string-to-replace/replace-with-string/`

Replace All occurence of string

`:%s/string-to-replace/replace-with-string/g`

Replace All occurence of string with confirmation

`:%s/string-to-replace/replace-with-string/gc`

### avoid staircase effect when pasting

If you're working in Vim and paste something into the terminal, sometimes you'll get a "staircase" effect where each line is progressively spaced farther outward, like so:

```
line 1
 line 2
  line 3
   line 4
```

Obviously, this isn't usually desirable.

To correct this, you can enable paste to prevent the staircase effect. In command mode, type:

`:set paste`

This isn't on by default. When paste is enabled, it disables mapping and some other functions, so you probably want to know how to turn it off as well:

`:set nopaste`

## Highlighting

syntax highlighting for programming languages

`:syntax on`

# Store settings

Put your most used commands, like *:syntax on* in ~/.vimrc

# statusline

`set statusline=%F%m%r%h%w%=\ [%Y]\ [%{&ff}]\ [%04l,%04v]\ [%p%%]\ [%L]`

in /etc/vimrc

# Verhuis een linux systeem naar nieuwe hardware

Verhuis van systeem A naar systeem B.

# Inpakken

- boot systeem A vanaf liveCD

<dl id="bkmrk-%28alternatief%3A-boot-i"><dt></dt><dd>(alternatief: boot in single-user-mode) </dd></dl>- mount de rootpartitie van systeem A:

`mount /dev/sda1 /mnt`

- mount het medium waarop het archief komt. Vaak automatisch, anders:

`mount /dev/sdf1 /media`

- ga naar root van (gemounte) filesysteem

`cd /mnt`

- (als je gebruikt maakt van de single-user-mode, dan cd / uiteraard)
- pak in:

`tar --one-file-system -cpf /media/systeem.tar * (-j=compressie)`

# Uitpakken

- boot systeem B vanaf liveCD
- maak nieuwe disk aan, en partitioneer. Bijvoorbeeld:

`fdisk /dev/sda`

<dl id="bkmrk-denk-er-ook-aan-om-e"><dt></dt><dd>denk er ook aan om een swap partitie aan te maken (type 82) </dd></dl>- maak bestandssystemen aan:

`mkfs.ext3 /dev/sda1`  
`mkswap /dev/sda2`  
`etc....`

- mount de doelpartitie en de gegevensdrager:

`mount /dev/sda1 /mnt`  
`mount /dev/sdf1 /media`

- pak het systeem uit:

`cd /mnt`  
`tar -xf /media/systeem.tar (-j als je compressie gebruikt)`

# Inrichten

- pas /etc/fstab aan, vervang bijvoorbeeld UUID's door apparaatnamen zoals /dev/sda1

`/dev/sda1   /     ext3   acl,user_xattr   1 1`  
`/dev/sda2   swap  swap   defaults         0 0`

- verwijder 2 udev regels voor netwerkkaarten en optische drives:

`rm /mnt/etc/udev/rules.d/70-persistent-cd.rules`  
`rm /mnt/etc/udev/rules.d/70-persistent-net.rules`

<dl id="bkmrk-deze-worden-na-boote"><dt></dt><dd>deze worden na booten opnieuw aangemaakt. </dd></dl>- pas /mnt/etc/X11/xorg.conf aan of wis deze zodat deze opnieuw wordt aangemaakt.

- pas GRUB aan: 
    - pas de 'root=' regel aan
    - vervang in /mnt/boot/grub/menu.lst UUID's door apparaatnamen zoals /dev/sda1

- mount nu de proc en dev bestandssystemen:

`mount -t proc none /mnt/proc`  
`mount -o bind /dev /mnt/dev`

- ga dan met chroot naar het nieuwe systeem:

`chroot /mnt`

- en installeer grub bootloader:

`grub-install /dev/sda (exit met CRTL-D)`

# A guide to using systemd

This is how to stop a running service temporarily:

`systemctl stop servicename.service`

Send a kill:

`systemctl kill sshd.service`  
`systemctl kill -s HUP sshd.service`

This stops it from starting at boot, but does not stop a running service:

`systemctl disable servicename.service`

And there is one way to really really stop a service for good, short of uninstalling it, and that is masking it by linking it to /dev/null:

`ln -s /dev/null /etc/systemd/system/servicename.service`  
`systemctl daemon-reload`

When you do this you can't even start the service manually. Nothing can touch it.

What if you change your mind? Pish tosh, it's easy. Simply delete the symlink and run

`systemctl enable servicename.service.`

While we're here, let's talk about two reload commands: daemon-reload and reload. The daemon-reload option reloads the entire systemd manager configuration without disrupting active services. reload reloads the configuration files for specific services without disrupting service, like this:

`systemctl reload servicename.service`

This reloads the actual configuration file used by the hardy sysadmin, for example the /etc/ssh/sshd\_config file for an SSH server, and not its systemd unit file, sshd.service. So this is what to use when you make configuration changes.

List active service units:

`systemctl --type=service`

list all service units:

`systemctl --type=service --all`

list systemd services:

`systemctl list-unit-files`

# default target

The system boots to **default.target**

This is a symbolic link to **multiuser.target** or **graphical.target**.

Changing the default runlevel/target is replacing the symbolic link

`ln -sf /lib/systemd/system/multi-user.target /etc/systemd/system/default.target`

To change runlevel:

`systemctl isolate multi-user.target`

# booting

At boot time, on the kernel grub line, add:

**`systemd.unit=xxxxx`**

So what's taking so long? We can find out with the systemd-analyze blame command

```
$ systemd-analyze blame
  60057ms sendmail.service
  51241ms firstboot-graphical.service
  3574ms sshd-keygen.service
  3439ms NetworkManager.service
  3101ms udev-settle.service
  3025ms netfs.service
  2411ms iptables.service
  2411ms ip6tables.service
  2173ms abrtd.service
  2149ms nfs-idmap.service
  2116ms systemd-logind.service
  2097ms avahi-daemon.service
  1337ms iscsi.service
```

If you like pretty graphs systemd includes a cool command for automatically generating an SVG image from the blame output, like this:

`systemd-analyze plot > graph1.svg`

To shutdown:

`systemctl poweroff`

# systemctl files

`/lib/systemd/system/ `  
`/etc/systemd/system/ is for customized settings`

# Perform bechmarks on the filesystem

- To test the speed of the filesystem (not the physical disk!) you can use the following script:

<div class="sourceCode" id="bkmrk-%23%21%2Fbin%2Fbash-%23-usage%3A">```
<span id="bkmrk-"><a aria-hidden="true" href="#bkmrk-" tabindex="-1"></a></span>
<span id="bkmrk-%23%21%2Fbin%2Fbash"><a aria-hidden="true" href="#bkmrk-%23%21%2Fbin%2Fbash" tabindex="-1"></a><span class="co">#!/bin/bash</span></span>
<span id="bkmrk--1"><a aria-hidden="true" href="#bkmrk--1" tabindex="-1"></a></span>
<span id="bkmrk-%23-usage%3A"><a aria-hidden="true" href="#bkmrk-%23-usage%3A" tabindex="-1"></a><span class="co"># USAGE:</span></span>
<span id="bkmrk-%23-.%2Fspeed_test.sh-%2Fp"><a aria-hidden="true" href="#bkmrk-%23-.%2Fspeed_test.sh-%2Fp" tabindex="-1"></a><span class="co"># ./speed_test.sh /path/to/my/file /path/to/destination number_of_tests</span></span>
<span id="bkmrk--2"><a aria-hidden="true" href="#bkmrk--2" tabindex="-1"></a></span>
<span id="bkmrk-num_tests%3D%243"><a aria-hidden="true" href="#bkmrk-num_tests%3D%243" tabindex="-1"></a><span class="va">NUM_TESTs</span><span class="op">=</span><span class="va">$3</span></span>
<span id="bkmrk-sum%3D0"><a aria-hidden="true" href="#bkmrk-sum%3D0" tabindex="-1"></a><span class="va">SUM</span><span class="op">=</span>0</span>
<span id="bkmrk-for-i-in-%24%28-seq-1-%24n"><a aria-hidden="true" href="#bkmrk-for-i-in-%24%28-seq-1-%24n" tabindex="-1"></a><span class="cf">for</span> i <span class="kw">in</span> <span class="va">$(</span> <span class="fu">seq</span> 1 <span class="va">$NUM_TESTs</span> <span class="va">)</span><span class="kw">;</span> <span class="cf">do</span></span>
<span id="bkmrk--3"><a aria-hidden="true" href="#bkmrk--3" tabindex="-1"></a></span>
<span id="bkmrk-rec%3D%60dd-if%3D%241-of%3D%242-"><a aria-hidden="true" href="#bkmrk-rec%3D%60dd-if%3D%241-of%3D%242-" tabindex="-1"></a><span class="va">REC</span><span class="op">=</span><span class="kw">`</span><span class="fu">dd</span> if=<span class="va">$1</span> of=<span class="va">$2</span> <span class="dv">2</span><span class="op">></span> some_random_file_ <span class="kw">;</span> <span class="fu">cat</span> some_random_file_ <span class="kw">|</span> <span class="fu">cut</span> <span class="at">-d</span> <span class="st">" "</span> <span class="at">-f8</span> <span class="kw">|</span> <span class="fu">tail</span> <span class="at">-1</span><span class="kw">`</span></span>
<span id="bkmrk--4"><a aria-hidden="true" href="#bkmrk--4" tabindex="-1"></a></span>
<span id="bkmrk-sum%3D%60echo-%24sum-%2B-%24re"><a aria-hidden="true" href="#bkmrk-sum%3D%60echo-%24sum-%2B-%24re" tabindex="-1"></a><span class="va">SUM</span><span class="op">=</span><span class="kw">`</span><span class="bu">echo</span> <span class="va">$SUM</span> + <span class="va">$REC</span> <span class="kw">|</span> <span class="fu">bc</span><span class="kw">`</span></span>
<span id="bkmrk--5"><a aria-hidden="true" href="#bkmrk--5" tabindex="-1"></a></span>
<span id="bkmrk-done"><a aria-hidden="true" href="#bkmrk-done" tabindex="-1"></a><span class="cf">done</span></span>
<span id="bkmrk--6"><a aria-hidden="true" href="#bkmrk--6" tabindex="-1"></a></span>
<span id="bkmrk-result%3D%60echo-%24sum-%2F-"><a aria-hidden="true" href="#bkmrk-result%3D%60echo-%24sum-%2F-" tabindex="-1"></a><span class="va">RESULT</span><span class="op">=</span><span class="kw">`</span><span class="bu">echo</span> <span class="va">$SUM</span> / <span class="va">$NUM_TESTs</span> <span class="kw">|</span> <span class="fu">bc</span> <span class="kw">|</span>  <span class="fu">awk</span> <span class="st">'{ str1=str1 $0 }END{ print str1 }'</span><span class="kw">`</span></span>
<span id="bkmrk--7"><a aria-hidden="true" href="#bkmrk--7" tabindex="-1"></a></span>
<span id="bkmrk-echo-%24result-mb%2Fs"><a aria-hidden="true" href="#bkmrk-echo-%24result-mb%2Fs" tabindex="-1"></a><span class="bu">echo</span> <span class="va">$RESULT</span> MB/s</span>
<span id="bkmrk--8"><a aria-hidden="true" href="#bkmrk--8" tabindex="-1"></a></span>
<span id="bkmrk-%23clean-up"><a aria-hidden="true" href="#bkmrk-%23clean-up" tabindex="-1"></a><span class="co">#clean up</span></span>
<span id="bkmrk-rm-some_random_file_"><a aria-hidden="true" href="#bkmrk-rm-some_random_file_" tabindex="-1"></a><span class="fu">rm</span> some_random_file_</span>
<span id="bkmrk-rm-%242"><a aria-hidden="true" href="#bkmrk-rm-%242" tabindex="-1"></a><span class="fu">rm</span> <span class="va">$2</span></span>
```

</div>- To make a big file, use

`cat /dev/zero > zerofile`

and abort it with CTRL-C after a few seconds.

Alternatively, you can use something like

`dd if=/dev/zero of=file.out bs=1MB count=500`

to create a 500MB file.

- Start the script like this:

`./speed_test.sh /mnt/sda1/zerofile /mnt/sdb1/zerofilecopy 3`

The result will be something like

`./speed_test.sh ./zerofile ./2delete 5`  
`237 MB/s`

# How to backup your disk with dd

I had several bad experiences losing my data in my life. Sometimes because of the hardware, sometimes because of my stupidness or inexperience. At least, it learned to be careful. I backup my data regularly, and on several support concerning the important ones.

I sometimes back up my primary partition, where the system is set. If my drive crashed, I want to recover quickly a system without having to reinstall hundreds of applications. I have used several times Partimage and was satisfied. But now I tend to use dd, which basically do the same thing in just one line. The advantage is that it is by default on any Linux distribution.

To back it up on an usb disk :

`$ sudo dd   if=/dev/hda1   |   gzip   -v   |   dd   of=/media/usbdisk/backup_hda1.gz`

To backup my home and other data partitions, I just copy the files manually, it is faster and there is no need to backup such a thing as the boot sector. But of course you could use the same command above.

When you wish to restore the partition to a new hard drive, just :

`$ zcat   /mnt/hdb5/sauvegarde.gz   |   dd   of=/dev/hda1`

To do that, you will have probably booted on a live CD Linux as Knoppix to restore the crashed system. In any case, don’t overwrite the system you just booted on !

One tip if you want to back up only the boot sector :

`$ sudo dd   if=/dev/hda   of=/home/secteur_boot.dd   bs=512   count=1`

And to restore :

`$ sudo dd   if=/home/secteur_boot.dd   of=/dev/hda   bs=512   count=1`

# Advanced options

`oflag=direct,sync`

for writing to slow devices such as SD cards, oflag=direct keeps it from filling up the process's memory with the backlogged output, and oflag=sync keeps it from filling up the kernel's memory.

direct is a good idea if you want to avoid buffering on the write end, but sync will severely degrade performance if the drive you're writing to does its own buffering. It will force every write to flush the drive's buffer too before moving on.

also: status=progress

# Things to clean up before doing large copy of entire system

- FF cache
- chromium cache
- .thumbnails
- spotify localstorecache
- .wine
- /var/tmp/kdecache-pvdm

# Linux commandline tips 4

trap ctrl-c in terminal:

`trap 'play -nq  synth sin 1000 trim 0 0.35 vol 0.5 2>/dev/null' INT`

watch if a website changes:

`while :;do curl -Ls "X\.com"|md5sum;sleep 5m;done|awk '{if(NR>1&&l!=$1){system("echo the site changed|mail -s NOTIFY you@isp\.net");};l=$1}'`

scan pdf to file. first extract the pages and ocr them, then make one doc

`pdfimages -tiff input.pdf plaatje`  
`for i in *.tif; do tesseract $i tempje-$i; done`  
`cat tempje-plaatje-0*.txt >> docje.txt`

ps ax -o state -o ppid | awk '$1=="Z"{print $2}' | xargs kill -9 # Kill all #zombies on the system.

ps aux |tail -n+2 |sort -nrk4 |head -$(($(tput lines)-1)) |cut -c 1-$(tput cols) # Display top RAM using processes.

ethtool -p eth0 # Blink eth0's LED so you can find it in the rat's next of server cables. Ctrl-C to stop.

find . -xdev -ls | sort -n -k 7 | tail -5 # Quickly find the largest 5 files in the CWD tree without crossing filesystem boundaries.

for f in \*; do b=$(echo "$f" | tr '\[A-Z\]' '\[a-z\]'); mv "$f" "$b"; done # Lower case all files in a folder.

rpm -qf $( which lspci ) # Pass the output of which (showing path to lspci) into rpm's -qf, which tells you the pkg.

rename -v 's/^(\[0-9\])\_/0\\1\_/' \*.flac # Rename all single leading digit flac files so that they have a padding 0 for easier sorting.

ps aux | awk '{if ($8=="Z") { print $2 }}'# On Linux, print out a list of the process IDs that are in the zombie state.

exiv2 -k -F rename \*.jpg # Use the exiv2 EXIF program to rename your jpg files according to their exif date/time data.

curl [http://wttr.in/castricum](http://wttr.in/castricum)\# see weatherforecast

finger amsterdam@graph.no

rpm -qa --queryformat "%{NAME} %{INSTALLTIME:date}\\n" | grep "Nov 2015" # In RPM, determine which packages where installed in Nov 2015.

echo "wall \\"hallo\\""| at 11:48 2016-02-27 # execute a command at a certain time and date

ls -la "$(find . -type f -printf '%T@ %p\\n' | sort -n | tail -1 | cut -f2- -d" ")" # show the most recent file in subtree

grep -Ev "((accept|drop|reject)log|ftpd)" /var/log/messages | less # Yes! You can do nested grouping in extended regexes.

With Bash history, `^str1^str2^` will repeat the previous command replacing `str1` by `str2`, so

`echo 1223`  
`^2^4^`

The #Bash has the notion of "integer" variable:

```
declare A=1; declare -i B=2
A+=3; B+=4
echo $A $B
⇒ 13 6
```

sort -t, -k5nr data.csv | less # Sort data.csv by the 5th column's numeric values in descending order.

Play a sound if you get an unsuccessful return code from last command.

`PROMPT_COMMAND='[ $? -ne 0 ] && play -qn synth sin G3 trim 0 0.1'`

Command used by P2V process:

`tar --one-file-system --sparse -C / -cf - .`

Show error warn and criticals in color:

`# tail -f "foo.log"|egrep --line-buffered --color=auto 'ERROR|WARN|CRITICAL$`

Very good overview of open ports and their programs:

`# lsof -Pan -i tcp -i udp`

To remove the hashtag parameter in a file and add the line if not exist; thus making sure the parameter is always present and enabled:

`# grep -qi 'ForwardToSyslog' /etc/systemd/journald.conf && sed -i 's/#ForwardToSyslog.*/ForwardToSyslog=Yes/' /etc/systemd/journald.conf || echo 'ForwardToSyslog=Yes' >> /etc/systemd/journald.conf`

# Linux algemeen

- fuser -ck /net

`pid of proccess holding mount`

`openssl x509 -noout -in scx-host-sldbowzs0101.basis-a.acc.pem  -text`

<div class="sourceCode" id="bkmrk-def-quicksort%28arr%29%3A-">```
<span id="bkmrk-def-quicksort%28arr%29%3A"><a aria-hidden="true" href="#bkmrk-def-quicksort%28arr%29%3A" tabindex="-1"></a><span class="kw">def</span> quickSort(arr):</span>
<span id="bkmrk-less-%3D-%5B%5D"><a aria-hidden="true" href="#bkmrk-less-%3D-%5B%5D" tabindex="-1"></a>    less <span class="op">=</span> []</span>
<span id="bkmrk-pivotlist-%3D-%5B%5D"><a aria-hidden="true" href="#bkmrk-pivotlist-%3D-%5B%5D" tabindex="-1"></a>    pivotList <span class="op">=</span> []</span>
<span id="bkmrk-more-%3D-%5B%5D"><a aria-hidden="true" href="#bkmrk-more-%3D-%5B%5D" tabindex="-1"></a>    more <span class="op">=</span> []</span>
<span id="bkmrk-if-len%28arr%29-%3C%3D-1%3A"><a aria-hidden="true" href="#bkmrk-if-len%28arr%29-%3C%3D-1%3A" tabindex="-1"></a>    <span class="cf">if</span> <span class="bu">len</span>(arr) <span class="op"><=</span> <span class="dv">1</span>:</span>
<span id="bkmrk-return-arr"><a aria-hidden="true" href="#bkmrk-return-arr" tabindex="-1"></a>        <span class="cf">return</span> arr</span>
<span id="bkmrk-else%3A"><a aria-hidden="true" href="#bkmrk-else%3A" tabindex="-1"></a>    <span class="cf">else</span>:</span>
```

</div><div class="sourceCode" id="bkmrk-def-quicksort%28arr%29%3A--1">```
<span id="bkmrk-def-quicksort%28arr%29%3A-1"><a aria-hidden="true" href="#bkmrk-def-quicksort%28arr%29%3A-1" tabindex="-1"></a><span class="ex">def</span> quickSort<span class="er">(</span><span class="ex">arr</span><span class="kw">)</span><span class="bu">:</span></span>
<span id="bkmrk-less-%3D-%5B%5D-1"><a aria-hidden="true" href="#bkmrk-less-%3D-%5B%5D-1" tabindex="-1"></a>    <span class="fu">less</span> = []</span>
<span id="bkmrk-pivotlist-%3D-%5B%5D-1"><a aria-hidden="true" href="#bkmrk-pivotlist-%3D-%5B%5D-1" tabindex="-1"></a>    <span class="ex">pivotList</span> = []</span>
<span id="bkmrk-more-%3D-%5B%5D-1"><a aria-hidden="true" href="#bkmrk-more-%3D-%5B%5D-1" tabindex="-1"></a>    <span class="fu">more</span> = []</span>
<span id="bkmrk-if-len%28arr%29-%3C%3D-1%3A-1"><a aria-hidden="true" href="#bkmrk-if-len%28arr%29-%3C%3D-1%3A-1" tabindex="-1"></a>    <span class="cf">if</span> <span class="ex">len</span><span class="er">(</span><span class="ex">arr</span><span class="kw">)</span> <span class="op"><</span>= <span class="ex">1:</span></span>
<span id="bkmrk-return-arr-1"><a aria-hidden="true" href="#bkmrk-return-arr-1" tabindex="-1"></a>        <span class="cf">return</span> <span class="ex">arr</span></span>
<span id="bkmrk-else%3A-1"><a aria-hidden="true" href="#bkmrk-else%3A-1" tabindex="-1"></a>    <span class="ex">else:</span></span>
```

</div>

# Awk

# awk

`pattern {action}`  
`pattern {action}`

`$ awk '{print $2}' /etc/fstab`

to filter out comment lines - starting with #

`$ awk '/^[^#]/ {print $2}' /etc/fstab`

to grep on TWO occurences (AND operator)

`$ awk '/pattern1/ && /pattern2/' /var/log/messages`

case insensitive

`$ awk '/pattern1/ && /pattern2/' IGNORECASE=1 /var/log/messages`

print first field from password file using field seperator ':'

`$ awk -F: '{print$1}' /etc/passwd`

print only user ID &gt; 500

`$ awk -F: '$3>=500 {print$1}' /etc/passwd`

display average of numbers entereed on a line:

`$ awk '{ sum=0; for (i=1; i<=NF; i++) sum +=$i; print sum/NF; }'`

<table id="bkmrk-nf-number-of-fields-"><tbody><tr><td>NF

</td><td>number of fields in the current line

</td></tr><tr><td>NR

</td><td>the current record number (line number)

</td></tr><tr><td>FS

</td><td>input field seperator (space by default)

</td></tr><tr><td>RS

</td><td>record seperator (newline by default)

</td></tr><tr><td>Example

</td><td>Example

</td></tr><tr><td>Example

</td><td>Example

</td></tr><tr><td>Example

</td><td>Example

</td></tr><tr><td>Example

</td><td>Example

</td></tr><tr><td>Example

</td><td>Example

</td></tr></tbody></table>

show the 5th record on the second line:

`df  /tmp | awk 'NR==2 {print$5 }'`

## use awk with a program

the file **maxuid**:

```
BEGIN {maxuid = 0; FS=":" }
{ if ($3 > maxuid) maxuid = $3 }
END { print" the largest UID is ", maxuid }
```

then use awk like this:

`$ awk -f maxuid /etc/passwd`

to ignore user nobody:

```
BEGIN {maxuid = 0; FS=":" }
$1 != "nobody" { if ($3 > maxuid) maxuid = $3 }
END { print" the largest UID is ", maxuid }
```

cat -n: (adds line numbers)

`$ awk '{ print NR, $0}' /etc/fstab`

wc -w: (count words)

`$ awk '{ w += NF } END { print w}' /etc/fstab`

grep chris /etc/passwd:

`$ awk '/^chris/' /etc/passwd`

## writing self contained scripts

```
#!/usr/bin/awk -f
{ cost[$1] += $2*$4 }
END { for (cat in cost) print cat, cost[cat] }
```

`chmod u+x catscript`  
`./catscript `

[http://www.pement.org/awk/awk1line.txt](http://www.pement.org/awk/awk1line.txt)

# Systemd journal log file setting

The new openSUSE 13.2 journald (from systemd) is sometimes quickly using up disk space.

There are setting you can tweak in /etc/systemd/journald.conf

```
[Journal]
Compress=yes
SystemMaxUse=500M
SystemKeepFree=2G
```

After that, restart the services **a few times** for the changes to take effect:

`systemctl restart systemd-journald.service `  
`systemctl restart systemd-journal-flush.service `

You should see a reduction in the size of the /var/log/ directory almost immediately.

# Dealing with spaces in filenames

BASH for loop works nicely under UNIX / Linux / Windows and OS X while working on set of files. However, if you try to process a for loop on file name with spaces in them you are going to have some problem. For loop uses $IFS variable to determine what the field separators are. By default $IFS is set to the space character. There are multiple solutions to this problem.

# Set $IFS variable

Try it as follows:

```
#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for f in *
do
  echo "$f"
done
IFS=$SAVEIFS
```

OR

```
#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
# set me
FILES=/data/*
for f in $FILES
do
  echo "$f"
done
# restore $IFS
IFS=$SAVEIFS
```

# More examples using $IFS and while loop

Now you know that if the field delimiters are not whitespace, you can set IFS. For example, while loop can be used to get all fields from /etc/passwd file:

```
....
while IFS=: read userName passWord userID groupID geCos homeDir userShell
do
      echo "$userName -> $homeDir"
done < /etc/passwd
```

source: [http://www.cyberciti.biz/tips/handling-filenames-with-spaces-in-bash.html](http://www.cyberciti.biz/tips/handling-filenames-with-spaces-in-bash.html)

# View progress of dd

In Linux, find running dd processes and send them a signal to print out their progress.

`kill -USR1 $( pidof dd )`

# Sort installed rpms by size

Sort installed RPMs by size

To list all RPM packages installed on a Linux machine sorted from the largest to the smallest in size:

`rpm -qa --queryformat '%{size} %{name}\n' | sort -rn | more`

# Command line tips

Show all VMs:

`vboxmanage list -l vms`

Show the state of the VM:

`vboxmanage showvminfo w7new | grep State`

Control the state of the VM:

`vboxmanage controlvm w7new pause|resume|reset|poweroff|savestate|`  
`                           acpipowerbutton|acpisleepbutton`

# Find

- [find latest files in all subdirectories per directory](https://www.reeltoreel.nl/knowledgebase/books/homelab/page/find-latest-files-in-all-subdirectories-per-directory)

# Find latest files in all subdirectories per directory

Create a file latestfile.sh:

<div class="sourceCode" id="bkmrk-%23%21%2Fbin%2Fbash-ls--lrt-">```
<span id="bkmrk-%23%21%2Fbin%2Fbash"><a aria-hidden="true" href="#bkmrk-%23%21%2Fbin%2Fbash" tabindex="-1"></a> <span class="co">#!/bin/bash</span></span>
<span id="bkmrk-ls--lrt-%22%241%22-%7C-tail-"><a aria-hidden="true" href="#bkmrk-ls--lrt-%22%241%22-%7C-tail-" tabindex="-1"></a> <span class="fu">ls</span> <span class="at">-lrt</span> <span class="st">"</span><span class="va">$1</span><span class="st">"</span> <span class="kw">|</span> <span class="fu">tail</span> <span class="at">-n1</span></span>
```

</div>Make it executable

`chmod +x ./latestfile.sh`

Then execute the following command:

`find . -mindepth 1 -type d -printf "%T+ %p/" -exec ./latestfile.sh {} \;`

Output:

```
2015-02-07+04:01:53.0000000000 ./$RCE/SLES11-SP2-Updates/sle-11-i586/repodata/repomd.xml.key
2015-02-07+04:02:09.0000000000 ./$RCE/SLES11-SP2-Updates/sle-11-i586/repodata
2015-02-07+04:07:41.0000000000 ./$RCE/SLES11-SP3-Pool/sle-11-i586/.repodata/repomd.xml.key
2015-02-07+04:07:41.0000000000 ./$RCE/SLES11-SP3-Pool/sle-11-i586/rpm
```

When outputted to a file (list.txt) then you could follow up with:

`cat list.txt | grep -v repomd | grep rpm | sort`

# Journald

output since booting:

`journalctl -b`

Follow:

`journalctl -f`

Keep an eye on sshd service:

`journalctl -b -f -l -u sshd`

Examples:

`journalctl -b --system`  
`journalctl -b --user`

`journalctl --since=yesterday`

`journalclt -b _PID=1`  
`journalclt -b _UID=1001`  
`journalclt -b /usr/bin/sudo`  
`journalctl KERNEL_DEVICE=+scsi:0:0:0:0`  
  
`-x -> extra info`

To monitor the output of dmesg:

`# journalctl -kf`

or

`# dmesg -wH`

# Sample commands

testdatabase 'testsietske';

```
> mysql -u root

MariaDB [testsietske]> use testsietske;

MariaDB [testsietske]> show tables;

MariaDB [testsietske]> select * from City;

MariaDB [testsietske]> select * from City where Countrycode = "NLD";

MariaDB [testsietske]> select * from City where District = "Noord-Holland";

MariaDB [testsietske]> select * from City where Countrycode = "NLD" and  population > "100000";


MariaDB [testsietske]> show tables;

MariaDB [testsietske]> select * from Country where Continent = "Europe";

----
```

- You can use db\_name.tbl\_name as an alternative to the tbl\_name FROM db\_name syntax. In other words, these two statements are equivalent:

```
 SHOW COLUMNS FROM City;
 MariaDB [testsietske]> SHOW COLUMNS FROM mytable FROM mydb;
 MariaDB [testsietske]> SHOW COLUMNS FROM mydb.mytable;
```

- show only first 10 results

```
 MariaDB [testsietske]> select * from City limit 10;
```

- show result 10 to 30

```
 MariaDB [testsietske]> select * from City limit 20 offset 10;
```

# Bash fun

pong:

`yes $COLUMNS $LINES|awk 'BEGIN{x=y=e=f=1}{if(x==$1||!x){e*=-1};if(y==$2||!y){f*=-1};x+=e;y+=f;printf "\033[%s;%sH",y,x;system("sleep .02")}'`

# OCR

scan pdf to file. first extract the pages and ocr them, then make one doc

`pdfimages -tiff input.pdf plaatje`  
`for i in *.tif; do tesseract $i tempje-$i; done`  
`cat tempje-plaatje-0*.txt >> docje.txt`

# Use tesseract to OCR a multi-page PDF file

First, convert the PDF to multiple TIFF files, because tesseract does not work with PDF.

Number the files with 2 digits at the end, remove the alfa-channel:

`# convert -density 300 inputfile.pdf -depth 8 -alpha off outputfile_%02d.tiff`

Then, use tesseract to make it into text:

`# tesseract inputfile.tiff outputfile`

if you do not provide and extension for the outputfile, it will become .txt

# Creating an overlay with the OCRed text

The newer version of Tesseract (3.03 RC at the time of writing this) can do this:

- free, opensource and cross-platform
- starting from version 3.03 PDF output is available
- CLI software
- multiple languages support
- unfortunately, single image input, so to make a complete document, one must create a batch script to convert each page image to searchable PDF. After that PDF pages should be combined to a single PDF using tools like pdftk.

This is the command:

`tesseract -l `<lang>` input.tif output pdf`</lang>

Note that in order to use this approach, the input PDF has to be rasterized first, since tesseract will not get PDF as input.

# To combine multiple PDF files into one

`# pdfunite output_*.pdf result.pdf`

# I have created a script

This script will do the work for you. Place the script in a directory together with the PDF to be processed, and run it.

```
#!/bin/bash

# converts a PDF containing scanned pages into a 
# new PDF file in which the OCRed text is overlayed,
# making the PDF searchable on text strings.

# use: 
#       doit.sh nice.PDF

# requires: tesseract-ocr, convert (ImageMagick), pdfunite, pdfinfo

# 20170417      1.0     PvdM    first version
# 20170418      1.1     PvdM    minor adjustment and improvements, mainly in the counter

bestand="$1"
newbestand=$(echo $bestand | cut -d"." -f1)_searchable.pdf
teller="0"
teller2="000"
aantpaginas=$(pdfinfo "$bestand" | grep 'Pages:' | awk '{ print $2 }')
RESTORE='\033[0m'
RED='\033[00;31m'
GREEN='\033[00;32m'
YELLOW='\033[00;33m'
BLUE='\033[00;34m'
PURPLE='\033[00;35m'
CYAN='\033[00;36m'
LIGHTGRAY='\033[00;37m'

function check_input {
if [ -z "$bestand" ]; then
        echo - Error. Usage:
        echo "         ./doit.sh input.pdf"; echo
        exit 1
fi
}

function check_error {
        if [ $? != 0 ]; then
                echo == Error! There was a problem in the command.
                exit 1
        fi
}

clear
echo "Converting PDF to searchable (overlay) PDF."
echo -e "-------------------------------------------\n"
check_input
echo -e " $bestand contains $RED $aantpaginas $RESTORE pages.\n"
echo " - (1/3) Extracting scanned PDF to images........"
convert -density 300 "$bestand" -depth 8 -alpha off temp_%03d.tiff
check_error
echo -e " - Done.\n"
echo

echo " - (2/3) Doing OCR on the images..........."
for i in temp_*.tiff; do
        tesseract -l eng $i temp_pdf_$teller2.pdf pdf
        check_error
        ((teller++))
        teller2=$(printf "%05d" $teller)
        echo -e " - (2/3) Doing OCR on the images. $RED Page $teller/$aantpaginas done.$RESTORE" 
done
echo -e " - Done.\n"
echo

echo " - (3/3) Combining the result into 1 (searchable) PDF"
pdfunite temp_pdf_*.pdf "$newbestand"
check_error
echo -e " - Done. $RED'$newbestand'$RESTORE created.\n"
rm temp*
```

# examples

## how to extract images from pdf

`pdfimages -all sm_td20a_very_detailed.pdf .`

`pdfimages -f 40 -l 41 -tiff hfe_teac_x-300_300r_service.pdf power-pcb`

# How to get into bios-setup

BIOS: when keyboardlight comes on, press and hold F2

# Ace

@tecra:~&gt; acestreamengine --client-console

@tecra:~&gt; acestream-launcher -p vlc acestream://67665adae9b7535a10f7b7a22d43f15683e78bde

[https://acestreamid.com/channel/sky-sports-f1](https://acestreamid.com/channel/sky-sports-f1)

# .vimrc

To support the creation and editing of yaml files in vi, set the following in ~/.vimrc

```
set expandtab
set tabstop=2
set autoindent
set shiftwidth=2
set softtabstop=2
set colorcolumn=3,5,7,9,11
set number
```

# Tips and tricks

Probably the best way to do this - assuming that you can't use the NOPASSWD solution provided by scottod is to use Mircea Vutcovici's solution in combination with Ansible vault.

For example, you might have a playbook something like this:

```
- hosts: all

  vars_files:
    - secret

  tasks:
    - name: Do something as sudo
      service: name=nginx state=restarted
      sudo: yes
```

Here we are including a file called secret which will contain our sudo password.

We will use ansible-vault to create an encrypted version of this file:

`ansible-vault create secret`

This will ask you for a password, then open your default editor to edit the file. You can put your ansible\_sudo\_pass in here.

e.g.: secret:

ansible\_sudo\_pass: mysudopassword

Save and exit, now you have an encrypted secret file which Ansible is able to decrypt when you run your playbook. Note: you can edit the file with ansible-vault edit secret (and enter the password that you used when creating the file)

The final piece of the puzzle is to provide Ansible with a --vault-password-file which it will use to decrypt your secret file.

Create a file called vault.txt and in that put the password that you used when creating your secret file. The password should be a string stored as a single line in the file.

From the Ansible Docs:

`   .. ensure permissions on the file are such that no one else can access your key and do not add your key to source control`

Finally: you can now run your playbook with something like

`ansible-playbook playbook.yml -u someuser -i hosts --sudo --vault-password-file=vault.txt `

The above is assuming the following directory layout:

```
.
|_ playbook.yml
|_ secret
|_ hosts
|_ vault.txt
```

You can read more about Ansible Vault here: [https://docs.ansible.com/playbooks\_vault.html](https://docs.ansible.com/playbooks_vault.html)

# Performance harddisk

# orginele harddisk

```
/dev/sda:

 Model=TOSHIBA THNSNK128GVN8, FwRev=K8TA4101, SerialNo=17CS14H7T8GT
 Config={ Fixed }
 RawCHS=16383/16/63, TrkSize=0, SectSize=0, ECCbytes=0
 BuffType=unknown, BuffSize=unknown, MaxMultSect=16, MultSect=off
 CurCHS=16383/16/63, CurSects=16514064, LBA=yes, LBAsects=250069680
 IORDY=on/off, tPIO={min:120,w/IORDY:120}, tDMA={min:120,rec:120}
 PIO modes:  pio0 pio3 pio4 
 DMA modes:  mdma0 mdma1 mdma2 
 UDMA modes: udma0 udma1 udma2 udma3 udma4 *udma5 
 AdvancedPM=yes: unknown setting WriteCache=enabled
 Drive conforms to: Unspecified:  ATA/ATAPI-3,4,5,6,7

 * signifies the current active mode

tecra:~ # hdparm -T /dev/sda

/dev/sda:
 Timing cached reads:   13074 MB in  1.99 seconds = 6579.23 MB/sec
tecra:~ # hdparm -T /dev/sda

/dev/sda:
 Timing cached reads:   13082 MB in  1.99 seconds = 6583.21 MB/sec
^[[Atecra:~ # hdparm -t /dev/sda

/dev/sda:
 Timing buffered disk reads: 1428 MB in  3.00 seconds = 475.35 MB/sec
tecra:~ # hdparm -t /dev/sda

/dev/sda:
 Timing buffered disk reads: 1404 MB in  3.00 seconds = 467.92 MB/sec
tecra:~ # 
```

# evo 970

# Bash pitfalls

# Bash Pitfalls

This page shows common errors that Bash programmers make. These examples are all flawed in some way.

You will save yourself from many of these pitfalls if you simply **[always use quotes](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/quotes)** and never use WordSplitting for any reason! Word splitting is a broken legacy misfeature inherited from the Bourne shell that's stuck on by default if you don't quote expansions. The vast majority of pitfalls are in some way related to unquoted expansions, and the ensuing word splitting and globbing that result.

&lt;<tableofcontents>&gt;</tableofcontents>

&lt;&lt;Anchor(pf1)&gt;&gt;

## for f in $(ls \*.mp3)

One of the most common mistakes [BASH](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/bash)programmers make is to write a loop like this:

```
for f in $(ls *.mp3); do    # Wrong!
    some command $i         # Wrong!
done

for f in $(ls)              # Wrong!
for f in `ls`               # Wrong!

for f in $(find . -type f)  # Wrong!
for f in `find . -type f`   # Wrong!

files=($(find . -type f))   # Wrong!
for f in ${files[@]}        # Wrong!
```

Yes, it would be great if you could just treat the output of `ls` or `find` as a list of filenames and iterate over it. But you **cannot**. This entire approach is fatally flawed, and there is no trick that can make it work. You must use an entirely different approach.

There are at least 6 problems with this:

- If a filename contains whitespace, it undergoes WordSplitting. Assuming we have a file named `01 - Don't Eat the Yellow Snow.mp3` in the current directory, the `for` loop will iterate over each word in the resulting file name: *01*, *-*, *Don't*, *Eat*, etc.
- If a filename contains [glob](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/glob)characters, it undergoes filename expansion ("[globbing](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/glob)"). If `ls` produces any output containing a **\*** character, the word containing it will become recognized as a pattern and substituted with a list of all filenames that match it.
- If the command substitution returns multiple filenames, there is no way to tell where the first one ends and the second one begins. Pathnames may contain *any* character except NUL. Yes, this includes newlines.
- The `ls` utility may mangle filenames. Depending on which platform you're on, which arguments you used (or didn't use), and whether its standard output is pointing to a terminal or not, `ls` may randomly decide to replace certain characters in a filename with "?", or simply not print them at all. [Never try to parse the output of ls](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/parsingls). `ls` is just plain unnecessary. It's an external command whose output is intended specifically to be read by a human, not parsed by a script.
- The CommandSubstitution strips *all* trailing newline characters from its output. That may seem desirable since `ls` adds a newline, but if the last filename in the list ends with a newline, ```
    `...`
    ```
    
    or `$()` will remove *that* one also.
- In the `ls` examples, if the first filename starts with a hyphen, it may lead to [pitfall #3](#pf3 "wikilink").

You can't simply double-quote the substitution either:

```
for f in "$(ls *.mp3)"; do     # Wrong!
```

This causes the entire output of `ls` to be treated as a single word. Instead of iterating over each file name, the loop will only execute *once*, assigning to `f` a string with all the filenames rammed together.

Nor can you simply change [IFS](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/ifs)to a newline. Filenames can also contain newlines.

Another variation on this theme is abusing word splitting and a `for` loop to (incorrectly) read lines of a file. For example:

```
IFS=$'\n'
for line in $(cat file); do ...     # Wrong!
```

[This doesn't work](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/dontreadlineswithfor)! Especially if those lines are filenames. Bash (or any other Bourne family shell) just doesn't work this way.

**So, what's the right way to do it?**

There are several ways, primarily depending on whether you need a recursive expansion or not.

If you don't need recursion, you can use a simple [glob](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/glob). Instead of `ls`:

```
for file in ./*.mp3; do    # Better! and...
    some command "$file"   # ...always double-quote expansions!
done
```

POSIX shells such as Bash have the globbing feature specifically for this purpose -- to allow the shell to expand patterns into a list of matching filenames. There is no need to interpret the results of an external utility. Because globbing is the very last expansion step, each match of the `./\*.mp3` pattern correctly expands to a separate word, and isn't subject to the effects of an unquoted expansion.

*Question:* What happens if there are no \*.mp3-files in the current directory? Then the for loop is executed once, with i="./\*.mp3", which is not the expected behavior! The workaround is to test whether there is a matching file:

```
# POSIX
for file in ./*.mp3; do
    [ -e "$file" ] || continue
    some command "$file"
done
```

Another solution is to use Bash's `shopt -s nullglob` feature, though this should only be done after reading the documentation and carefully considering the effect of this setting on all other globs in the script.

If you need recursion, the standard solution is `find`. When [using find](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/usingfind), be sure you use it properly. For POSIX sh portability, use the `-exec` option:

```
find . -type f -name '*.mp3' -exec some command {} \;

# Or, if the command accepts multiple input filenames:

find . -type f -name '*.mp3' -exec some command {} +
```

If you're using bash, then you have two additional options. One is to use GNU or BSD `find`'s `-print0` option, together with bash's `read -d ''` option and a ProcessSubstitution:

```
while IFS= read -r -d '' file; do
  some command "$file"
done < <(find . -type f -name '*.mp3' -print0)
```

The advantage here is that "some command" (indeed, the entire `while` loop body) is executed in the current shell. You can set variables and have them [persist after the loop ends](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/bashfaq024).

The other option, available in [Bash 4.0 and higher](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/bashfaq061), is `globstar`, which permits a glob to be expanded recursively:

```
shopt -s globstar
for file in ./**/*.mp3; do
  some command "$file"
done
```

Note the double quotes around `$file` in the examples above. This leads to our second pitfall:

&lt;&lt;Anchor(pf2)&gt;&gt;

## cp $file $target

What's wrong with the command shown above? Well, nothing, **if** you happen to know in advance that `$file` and `$target` have no white space or [wildcards](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/glob)in them. However, the results of the expansions are still subject to WordSplitting and [pathname expansion](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/glob). Always double-quote parameter expansions.

```
cp -- "$file" "$target"
```

Without the double quotes, you'll get a command like `cp 01 - Don't Eat the Yellow Snow.mp3 /mnt/usb`, which will result in errors like

```
cp: cannot stat `01': No such file or directory
```

. If `$file` has wildcards in it (**\*** or **?** or **\[**), they will be [expanded](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/glob)if there are files that match them. With the double quotes, all's well, unless "$file" happens to start with a `-`, in which case `cp` thinks you're trying to feed it command line options (See [pitfall #3](#pf3 "wikilink") below.)

Even in the somewhat uncommon circumstance that you can guarantee the variable contents, it is conventional and good practice to [quote](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/quotes)parameter expansions, especially if they contain file names. Experienced script writers will always use [quotes](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/quotes)except perhaps for a small number of cases in which it is *absolutely* obvious from the immediate code context that a parameter contains a guaranteed safe value. Experts will most likely consider the `cp` command in the title always wrong. You should too.

&lt;&lt;Anchor(pf3)&gt;&gt;

## Filenames with leading dashes

Filenames with leading dashes can cause many problems. Globs like `\*.mp3` are sorted into an expanded list (according to your current [locale](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/locale)), and `-` sorts before letters in most locales. The list is then passed to some command, which may incorrectly interpret the `-filename` as an option. There are two major solutions to this.

One solution is to insert `--` between the command (like `cp`) and its arguments. That tells it to stop scanning for options, and all is well:

```
cp -- "$file" "$target"
```

There are potential problems with this approach. You have to be sure to insert `--` for *every* usage of the parameter in a context where it might possibly be interpreted as an option -- which is easy to miss and may involve a lot of redundancy.

Most well-written option parsing libraries understand this, and the programs that use them correctly should inherit that feature for free. However, still be aware that it is ultimately up to the application to recognize *end of options*. Some programs that manually parse options, or do it incorrectly, or use poor 3rd-party libraries may not recognize it. Standard utilities *should*, with a few exceptions that are specified by POSIX. `echo` is one example.

Another option is to ensure that your filenames always begin with a directory by using relative or absolute pathnames.

```
for i in ./*.mp3; do
    cp "$i" /target
    ...
done
```

In this case, even if we have a file whose name begins with `-`, the glob will ensure that the variable always contains something like `./-foo.mp3`, which is perfectly safe as far as `cp` is concerned.

Finally, if you can guarantee that all results will have the same prefix, and are only using the variable a few times within a loop body, you can simply concatenate the prefix with the expansion. This gives a theoretical savings in generating and storing a few extra characters for each word.

```
for i in *.mp3; do
    cp "./$i" /target
    ...
done
```

&lt;&lt;Anchor(pf4)&gt;&gt;

== \[ $foo = "bar" \] == This is very similar to the issue in pitfall #2, but I repeat it because it's *so* important. In the example above, the [quotes](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/quotes)are in the wrong place. You do *not* need to quote a string literal in bash (unless it contains metacharacters or pattern characters). But you *should* quote your variables if you aren't sure whether they could contain white space or wildcards.

This example can break for several reasons:

`* If a variable referenced in `[` doesn't exist, or is blank, then the `[` command would end up looking like:`  
`. `

```
[ = "bar" ] # Wrong!
```

`. ...and will throw the error: `unary operator expected`. (The `=` operator is `*`binary`*`, not unary, so the `[` command is rather shocked to see it there.)`

`* If the variable contains internal whitespace, then it gets `[`split into separate words`](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/wordsplitting)` before the `[` command sees it. Thus:`  
`. `

```
[ multiple words here = "bar" ]
```

`. While that may look OK to you, it's a syntax error as far as `[` is concerned. The correct way to write this is:`  
`. `

```
# POSIX
[ "$foo" = bar ] # Right!
```

`. This works fine on POSIX-conformant implementations even if `$foo` begins with a `-`, because POSIX `[` determines its action depending on the number of arguments passed to it. Only very ancient shells have a problem with this, and you shouldn't worry about them when writing new code (see the `x"$foo"` workaround below).`

In Bash and many other ksh-like shells, there is a superior alternative which uses the \[\[BashFAQ/031|[keyword](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/keyword).

```
# Bash / Ksh
[[ $foo == bar ]] # Right!
```

You don't need to quote variable references on the left-hand side of `=` in `[](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/)` because they don't undergo word splitting or [globbing](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/glob), and even blank variables will be handled correctly. On the other hand, quoting them won't hurt anything either. Unlike `\[` and `test`, you may also use the identical `==`. Do note however that comparisons using `[` perform pattern matching against the string on the right hand side, not just a plain string comparison. To make the string on the right literal, you must quote it if any characters that have special meaning in pattern matching contexts are used. &lt;pre&gt; # Bash / Ksh match=b\*r \[\[ $foo == "$match"](`_perform_pattern_matching_against_the_string_on_the_right_hand_side,_not_just_a_plain_string_comparison._To_make_the_string_on_the_right_literal,_you_must_quote_it_if_any_characters_that_have_special_meaning_in_pattern_matching_contexts_are_used._<pre>_#_Bash_/_Ksh_match=b*r_[[_$foo_==_"$match" "wikilink") # Good! Unquoted would also match against the pattern b\*r.

You may have seen code like this:

```
# POSIX / Bourne
[ x"$foo" = xbar ] # Ok, but usually unnecessary.
```

The `x"$foo"` hack is required for code that must run on *very* ancient shells which lack \[\[BashFAQ/031|[](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/), and have a more primitive `\[`, which gets confused if `$foo` begins with a `-`. On said older systems, `\[` still doesn't care whether the token on the right hand side of the `=` begins with a `-`. It just uses it literally. It's just the left-hand side that needs extra caution.

Note that shells that require this workaround are not POSIX-conforming. Even the Heirloom Bourne shell doesn't require this (probably the non-POSIX Bourne shell clone that's still most widely in use as a system shell). Such extreme portability is rarely a requirement and makes your code less readable (and uglier).

&lt;&lt;Anchor(pf5)&gt;&gt;

## cd $(dirname "$f")

This is yet another [quoting](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/quotes)error. As with a variable expansion, the result of a CommandSubstitution undergoes WordSplitting and [pathname expansion](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/glob). So you should quote it:

```
cd -P -- "$(dirname -- "$f")"
```

What's not obvious here is how the [quotes](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/quotes)nest. A C programmer reading this would expect the first and second double-quotes to be grouped together; and then the third and fourth. But that's not the case in Bash. Bash treats the double-quotes *inside* the command substitution as one pair, and the double-quotes *outside* the substitution as another pair.

Another way of writing this: the parser treats the command substitution as a "nesting level", and the quotes inside it are separate from the quotes outside it.

&lt;&lt;Anchor(pf6)&gt;&gt;

== \[ "$foo" = bar &amp;&amp; "$bar" = foo \] == You can't use `&amp;&amp;` inside the [old test (or \[) command](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/bashfaq031). The Bash parser sees `&amp;&amp;` outside of `[](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/)` or `(( ))` and breaks your command into *two* commands, before and after the `&amp;&amp;`. Use one of these instead:

```
[ bar = "$foo" ] && [ foo = "$bar" ] # Right! (POSIX)
[[ $foo = bar && $bar = foo ]]       # Also right! (Bash / Ksh)
```

(Note that we reversed the constant and the variable inside `\[` for the legacy reasons discussed in pitfall #4. We could also have reversed the `\[\[` case, but the expansions would require quoting to prevent interpretation as a pattern.) The same thing applies to `||`. Either use `\[\[` instead, or use two `\[` commands.

Avoid this:

```
[ bar = "$foo" -a foo = "$bar" ] # Not portable.
```

The binary `-a` and `-o`, and `(` / `)` (grouping) operators are XSI extensions to the POSIX standard. All are marked as obsolescent in POSIX-2008. They should not be used in new code. One of the practical problems with `\[ A = B -a C = D \]` (or `-o`) is that [POSIX does not specify](http://www.opengroup.org/onlinepubs/9699919799/utilities/test.html "wikilink") the results of a `test` or `\[` command with more than 4 arguments. It probably works in most shells, but you can't count on it. If you have to write for POSIX shells, then you should use two `test` or `\[` commands separated by a `&amp;&amp;` operator instead.

&lt;&lt;Anchor(pf7)&gt;&gt;

## [$foo &gt; 7]($foo_>_7 "wikilink")

There are multiple issues here. First, the \[\[BashFAQ/031|[command](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/command)should *not* be used solely for evaluating [arithmetic expressions](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/arithmeticexpression). It should be used for test expressions involving one of the supported test operators. Though technically you *can* do math using some of `[`'s operators, it only makes sense to do so in conjunction with one of the non-math test operators somewhere in the expression. If you just want to do a numeric comparison (or any other shell arithmetic), it is much better to just use `(( ))` instead: &lt;pre&gt; # Bash / Ksh ((foo &gt; 7)) # Right! \[\[ foo -gt 7](`'s_operators,_it_only_makes_sense_to_do_so_in_conjunction_with_one_of_the_non-math_test_operators_somewhere_in_the_expression._If_you_just_want_to_do_a_numeric_comparison_(or_any_other_shell_arithmetic),_it_is_much_better_to_just_use_`((_))`_instead:_<pre>_#_Bash_/_Ksh_((foo_>_7))_#_Right!_[[_foo_-gt_7 "wikilink") # Works, but is pointless. Most will consider it wrong. Use ((...)) or let instead.

If you use the `&gt;` operator inside `[](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/)`, it's treated as a string comparison (test for collation order by locale), *not* an integer comparison. This may work sometimes, but it will fail when you least expect it. If you use `&gt;` inside `\[ \]`, it's even worse: it's an output redirection. You'll get a file named `7` in your directory, and the test will succeed as long as `$foo` is not empty.

If strict POSIX-conformance is a requirement, and `((` is not available, then the correct alternative using old-style `\[` is

```
# POSIX
[ "$foo" -gt 7 ]       # Also right!
[ $((foo > 7)) -ne 0 ] # POSIX-compatible equivalent to ((, for more general math operations.
```

Note that the `test ... -gt` command will fail in interesting ways if `$foo` is [not an integer](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/bashfaq054). Therefore, there's not much point in quoting it properly other than for performance and to confine the arguments to a single word to reduce the likelihood of obscure side-effects possible in some shells.

If the input to any arithmetic context (including `((` or `let`), or `\[` test expression involving numeric comparisons can't be guaranteed then you must *always* [validate your input before evaluating the expression](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/bashfaq054).

```
# POSIX
case $foo in
    *[![:digit:]]*)
        printf '$foo expanded to a non-digit: %s\n' "$foo" >&2
        exit 1
        ;;
    *)
        [ $foo -gt 7 ]
esac
```

&lt;&lt;Anchor(pf8)&gt;&gt;

## grep foo bar | while read -r; do ((count++)); done

The code above looks OK at first glance, doesn't it? Sure, it's just a poor implementation of `grep -c`, but it's intended as a simplistic example. Changes to `count` won't propagate outside the `while` loop because each command in a pipeline is executed in a separate SubShell. This surprises almost every Bash beginner at some point.

POSIX doesn't specify whether or not the last element of a pipeline is evaluated in a subshell. Some shells such as ksh93 and Bash &gt;= 4.2 with `shopt -s lastpipe` enabled will run the `while` loop in this example in the original shell process, allowing any side-effects within to take effect. Therefore, portable scripts must be written in such a way as to not depend upon either behavior.

For workarounds for this and similar issues, please see [Bash FAQ #24](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/bashfaq024). It's a bit too long to fit here.

&lt;&lt;Anchor(pf9)&gt;&gt;

## if \[grep foo myfile\]

Many beginners have an incorrect intuition about `if` statements brought about by seeing the very common pattern of an `if` keyword followed immediately by a `\[` or `\[\[`. This convinces people that the `\[` is somehow part of the `if` statement's syntax, just like parentheses used in C's `if` statement.

This is *not* the case! `if` takes a *command*. `\[` is a command, not a syntax marker for the `if` statement. It's equivalent to the `test` command, except that the final argument must be a `\]`. For example:

```
# POSIX
if [ false ]; then echo "HELP"; fi
if test false; then echo "HELP"; fi
```

are equivalent -- both checking that the argument "false" is non-empty. In both cases HELP will always be printed, to the surprise of programmers from other languages guessing about shell syntax.

The syntax of an `if` statement is:

```
if COMMANDS
then <COMMANDS>
elif <COMMANDS> # optional
then <COMMANDS>
else <COMMANDS> # optional
fi # required
```

Once again, `\[` is a command. It takes arguments like any other regular *simple command*. `if` is a *compound command*which contains other commands -- and **there is no \[** in its syntax!

While bash has a builtin command `\[` and thus `knows` about `\[` it has nothing special to do with `\]`. Bash only passes `\]` as argument to the `\[` command, which requires `\]` to be the last argument only to make scripts look better.

There may be zero or more optional `elif` sections, and one optional `else` section.

The `if` compound command is made up of two or more sections containing *lists* of commands, each delimited by a `then`, `elif`, or `else` keyword, and is terminated by the `fi` keyword. The exit status of the final command of the first section and each subsequent `elif` section determines whether each corresponding `then` section is evaluated. Another `elif` is evaluated until one of the `then` sections is executed. If no `then` section is evaluated, then the `else` branch is taken, or if no `else` is given, the `if` block is complete and the overall `if` command returns 0 (true).

If you want to make a decision based on the output of a `grep` command, you do *not* want to enclose it in parentheses, brackets, backticks, or *any other* syntax! Just use `grep` as the `COMMANDS` after the `if`, like this:

```
if grep -q fooregex myfile; then
...
fi
```

If the `grep` matches a line from `myfile`, then the exit code will be 0 (true), and the `then` part will be executed. Otherwise, if there are no matches, `grep` will return non-zero and the overall `if` command will be zero.

**See also:**

`* BashGuide/TestsAndConditionals`  
`* `[`http://wiki.bash-hackers.org/syntax/ccmd/if_clause`](http://wiki.bash-hackers.org/syntax/ccmd/if_clause)

&lt;&lt;Anchor(pf10)&gt;&gt;

== if \[bar="$foo"\]; then ... ==

```
[bar="$foo"]   # Wrong!
[ bar="$foo" ] # Still wrong!
```

As explained in the previous example, `\[` is a command (which can be proven with `type -t \[` or `whence -v \[`). Just like with any other simple command, Bash expects the command to be followed by a space, then the first argument, then another space, etc. You can't just run things all together without putting the spaces in! Here is the correct way:

```
if [ bar = "$foo" ]; then ...
```

Each of `bar`, `=`, the expansion of `"$foo"`, and `\]` is a separate [argument](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/arguments)to the `\[` command. There must be whitespace between each pair of arguments, so the shell knows where each argument begins and ends.

&lt;&lt;Anchor(pf11)&gt;&gt;

== if \[ \[ a = b \] &amp;&amp; \[ c = d \] \]; then ... == Here we go again. `\[` is a *command*. It is not a syntactic marker that sits between `if` and some sort of C-like "condition". Nor is it used for grouping. You cannot take C-like `if` commands and translate them into Bash commands just by replacing parentheses with square brackets!

If you want to express a compound conditional, do this:

```
if [ a = b ] && [ c = d ]; then ...
```

Note that here we have two *commands* after the `if`, joined by an `&amp;&amp;` (logical AND, shortcut evaluation) operator. It's precisely the same as:

```
if test a = b && test c = d; then ...
```

If the first `test` command returns false, the body of the `if` statement is not entered. If it returns true, then the second `test` command is run; and if that also one returns true, then the body of the `if` statement *will* be entered. (C programmers are already familiar with `&amp;&amp;`. Bash uses the same *short-circuit evaluation*. Likewise `||` does short-circuit evaluation for the *OR* operation.)

The \[\[BashFAQ/031|[keyword](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/keyword)*does* permit the use of `&amp;&amp;`, so it could also be written this way:

```
if [[ a = b && c = d ]]; then ...
```

See [pitfall #6](#pf6 "wikilink") for a pitfall related to *tests* combined with conditional operators.

&lt;&lt;Anchor(pf12)&gt;&gt;

## read $foo

You don't use a `$` before the variable name in a `read` command. If you want to put data into the variable named `foo`, you do it like this:

`. `

```
 read foo
```

Or more safely:

`. `

```
 IFS= read -r foo
```

`read $foo` would read a line of input and put it in the variable(s) whose name(s) are in `$foo`. This might be useful if you actually intended `foo` to be a [reference](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/bashfaq006)to some other variable; but in the majority of cases, this is simply a bug.

&lt;&lt;Anchor(pf13)&gt;&gt;

## cat file | sed s/foo/bar/ &gt; file

You **cannot** read from a file and write to it in the same pipeline. Depending on what your pipeline does, the file may be clobbered (to 0 bytes, or possibly to a number of bytes equal to the size of your operating system's pipeline buffer), or it may grow until it fills the available disk space, or reaches your operating system's file size limitation, or your quota, etc.

If you want to make a change to a file safely, other than appending to the end of it, use a text editor.

`. `

```
 printf %s\\n ',s/foo/bar/g' w q | ed -s file
```

If you are doing something that cannot be done with a text editor there *must* be a temporary file created at some point(\*). For example, the following is completely portable:

`. `

```
 sed 's/foo/bar/g' file > tmpfile && mv tmpfile file
```

The following will *only* work on GNU sed 4.x:

`. `

```
 sed -i 's/foo/bar/g' file(s)
```

Note that this also creates a temporary file, and does the same sort of renaming trickery -- it just handles it transparently.

And the following equivalent command requires perl 5.x (which is probably more widely available than GNU sed 4.x):

`. `

```
 perl -pi -e 's/foo/bar/g' file(s)
```

For more details on replacing contents of files, please see [Bash FAQ #21](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/bashfaq021).

(\*) `sponge` from [moreutils](http://packages.debian.org/sid/moreutils "wikilink") uses this example in its manual:

`. `

```
 sed '...' file | grep '...' | sponge file
```

Rather than using a temporary file plus an atomic `mv`, this version "soaks up" (the actual description in the manual!) all the data, before opening and writing to the `file`. This version will cause data loss if the program or system crashes during the write operation, because there's no copy of the original file on disk at that point.

Using a temporary file + `mv` still incurs a slight risk of data loss in case of a system crash / power loss; to be 100% certain that either the old or the new file will survive a power loss, you must use `sync` before the `mv`.

&lt;&lt;Anchor(pf14)&gt;&gt;

## echo $foo

This relatively innocent-looking command causes *massive*confusion. Because the `$foo` isn't [quoted](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/quotes), it will not only be subject to WordSplitting, but also file [globbing](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/glob). This misleads Bash programmers into thinking their variables *contain* the wrong values, when in fact the variables are OK -- it's just the word splitting or filename expansion that's messing up their view of what's happening.

`. `

```
 msg="Please enter a file name of the form *.zip"
 echo $msg
```

This message is split into words and any globs are expanded, such as the \*.zip. What will your users think when they see this message:

`. `

```
 Please enter a file name of the form freenfss.zip lw35nfss.zip
```

To demonstrate:

`. `

```
 var="*.zip"   # var contains an asterisk, a period, and the word "zip"
 echo "$var"   # writes *.zip
 echo $var     # writes the list of files which end with .zip
```

In fact, the `echo` command cannot be used with absolute safety here. If the variable contains `-n` for example, `echo` will consider that an option, rather than data to be printed. The only absolutely *sure* way to print the value of a variable is using `printf`:

`. `

```
 printf "%s\n" "$foo"
```

&lt;&lt;Anchor(pf15)&gt;&gt;

== $foo=bar == No, you don't assign a variable by putting a `$` in front of the variable name. This isn't perl.

&lt;&lt;Anchor(pf16)&gt;&gt;

== foo = bar == No, you can't put spaces around the `=` when assigning to a variable. This isn't C. When you write `foo = bar` the shell splits it into three words. The first word, `foo`, is taken as the command name. The second and third become the arguments to that command.

Likewise, the following are also wrong:

`. `

```
 foo= bar    # WRONG!
 foo =bar    # WRONG!
 $foo = bar; # COMPLETELY WRONG!

 foo=bar     # Right.
 foo="bar"   # More Right.
```

&lt;&lt;Anchor(pf17)&gt;&gt;

## echo &lt;&lt;EOF

A here document is a useful tool for embedding large blocks of textual data in a script. It causes a redirection of the lines of text in the script to the standard input of a command. Unfortunately, `echo` is not a command which reads from stdin.

`. `

```
  # This is wrong:
  echo <<EOF
  Hello world
  How's it going?
  EOF

  # This is what you were trying to do:
  cat <<EOF
  Hello world
  How's it going?
  EOF

  # Or, use quotes which can span multiple lines (efficient, echo is built-in):
  echo "Hello world
  How's it going?"
```

Using quotes like that is fine -- it works great, in all shells -- but it doesn't let you just drop a block of lines into the script. There's syntactic markup on the first and last line. If you want to have your lines untouched by shell syntax, and don't want to spawn a `cat` command, here's another alternative:

`. `

```
  # Or use printf (also efficient, printf is built-in):
  printf %s "\
  Hello world
  How's it going?
  "
```

In the `printf` example, the `\\` on the first line prevents an extra newline at the beginning of the text block. There's a literal newline at the end (because the final quote is on a new line). The lack of `\\n` in the printf format argument prevents `printf` adding an extra newline at the end. The `\\` trick won't work in single quotes. If you need/want single quotes around the block of text, you have two choices, both of which necessitate shell syntax "contaminating" your data:

`. `

```
  printf %s \
  'Hello world
  '

  printf %s 'Hello world
  '
```

&lt;&lt;Anchor(pf18)&gt;&gt;

## su -c 'some command'

This syntax is *almost* correct. The problem is, on many platforms, `su` takes a `-c` argument, but it's not the one you want. For example, on OpenBSD:

`. `

```
 $ su -c 'echo hello'
 su: only the superuser may specify a login class
```

You want to pass `-c 'some command'` to a shell, which means you need a username before the `-c`.

`. `

```
 su root -c 'some command' # Now it's right.
```

`su` assumes a username of root when you omit one, but this falls on its face when you want to pass a command to the shell afterward. You must supply the username in this case.

&lt;&lt;Anchor(pf19)&gt;&gt;

## cd /foo; bar

If you don't check for errors from the `cd` command, you might end up executing `bar` in the wrong place. This could be a major disaster, if for example `bar` happens to be `rm -f \*`.

You must **always** check for errors from a `cd` command. The simplest way to do that is:

`. `

```
 cd /foo && bar
```

If there's more than just one command after the `cd`, you might prefer this:

`. `

```
 cd /foo || exit 1
 bar
 baz
 bat ... # Lots of commands.
```

`cd` will report the failure to change directories, with a stderr message such as "bash: cd: /foo: No such file or directory". If you want to add your own message in stdout, however, you could use command grouping:

`. `

```
 cd /net || { echo >&2 "Can't read /net. Make sure you've logged in to the Samba network, and try again."; exit 1; }
 do_stuff
 more_stuff
```

Note there's a required space between `{` and `echo`, and a required `;` before the closing `}`. You could also write a `die` function, if you prefer.

Some people also like to enable [set -e](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/bashfaq105) to make their scripts abort on *any* command that returns non-zero, but this can be [rather tricky to use correctly](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/bashfaq105) (since many common commands may return a non-zero for a warning condition, which you may not want to treat as fatal).

By the way, if you're changing directories a lot in a Bash script, be sure to read the Bash help on `pushd`, `popd`, and `dirs`. Perhaps all that code you wrote to manage `cd`'s and `pwd`'s is completely unnecessary.

Speaking of which, compare this:

`. `

```
 find ... -type d -print0 | while IFS= read -r -d '' subdir; do
   here=$PWD
   cd "$subdir" && whatever && ...
   cd "$here"
 done
```

With this:

`. `

```
 find ... -type d -print0 | while IFS= read -r -d '' subdir; do
   (cd "$subdir" || exit; whatever; ...)
 done
```

Forcing a SubShell here causes the `cd` to occur only in the subshell; for the next iteration of the loop, we're back to our normal location, regardless of whether the `cd` succeeded or failed. We don't have to change back manually, and we aren't stuck in a neverending string of `... &amp;&amp; ...` logic preventing the use of other conditionals. The subshell version is simpler and cleaner (albeit a tiny bit slower).

Another approach is to `cd` unconditionally to where we're supposed to be, at the start of each loop iteration:

`. `

```
 here=$PWD
 find ... -type d -print0 | while IFS= read -r -d '' subdir; do
    cd "$here" || continue
    cd "$subdir" || continue
    whatever
    ...
 done
```

At least this way, we can `continue` to the next loop iteration and don't have to string an indefinite series of `&amp;&amp;` together to ensure that we reach the `cd` at the end of the loop body.

&lt;&lt;Anchor(pf20)&gt;&gt;

## \[ bar

"$foo" \] == The `==` operator is not valid for the POSIX `\[` command. Use `=` or the \[\[BashFAQ/031|[keyword](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/keyword)instead.

`. `

```
 [ bar = "$foo" ] && echo yes
 [[ bar == $foo ]] && echo yes
```

In Bash, `\[ "$x" == y \]` is accepted as an extension, which often leads Bash programmers to think it's the correct syntax. It's not; it's a [Bashism](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/bashism). If you're going to use Bashisms, you might as well just use `\[\[` instead.

&lt;&lt;Anchor(pf21)&gt;&gt;

## for i in {1..10}; do ./something &amp;; done

You *cannot* put a `;` immediately after an `&amp;`. Just remove the extraneous `;` entirely.

`. `

```
 for i in {1..10}; do ./something & done
```

Or:

`. `

```
 for i in {1..10}; do
   ./something &
 done
```

`&amp;` already functions as a command terminator, just like `;` does. And you cannot mix the two.

In general, a `;` can be replaced by a newline, but not all newlines can be replaced by `;`.

&lt;&lt;Anchor(pf22)&gt;&gt;

## cmd1 &amp;&amp; cmd2 || cmd3

Some people try to use `&amp;&amp;` and `||` as a shortcut syntax for `if ... then ... else ... fi`, perhaps because they think they are being clever. For instance,

`. `

```
 # WRONG!
 [[ -s $errorlog ]] && echo "Uh oh, there were some errors." || echo "Successful."
```

However, this construct is *not* completely equivalent to `if ... fi` in the general case. The command that comes after the `&amp;&amp;` also generates an exit status, and if that exit status isn't "true" (0), then the command that comes after the `||` will *also* be invoked. For example:

`. `

```
 i=0
 true && ((i++)) || ((i--))  # WRONG!
 echo "$i"                   # Prints 0
```

What happened here? It looks like `i` should be 1, but it ends up 0. Why? Because both the `i++` *and* the `i--` were executed. The `((i++))` command has an exit status, and that exit status is derived from a C-like evaluation of the expression inside the parentheses. That expression's value happens to be 0 (the initial value of `i`), and in C, an expression with an integer value of 0 is considered *false*. So `((i++))` (when `i` is 0) has an exit status of 1 (false), and therefore the `((i--))` command is executed as well.

Another clever person thinks that we can fix it by using the pre-increment operator, since the exit status from `++i` (with `i` initially 0) is true:

`. `

```
 i=0
 true && (( ++i )) || (( --i ))  # STILL WRONG!
 echo "$i"                       # Prints 1 by dumb luck
```

But that's missing the point of the example. It just *happens*to work by *coincidence*, and you *cannot* rely on `x &amp;&amp; y || z` if `y` has **any** chance of failure! (This example still fails if we initialize `i` to -1 instead of 0.)

If you need safety, or if you simply aren't sure how this works, or if *anything* in the preceding paragraphs wasn't completely clear, please just use the simple `if ... fi` syntax in your programs.

`. `

```
 i=0
 if true; then
   ((i++))
 else
   ((i--))
 fi
 echo "$i"    # Prints 1
```

This section also applies to Bourne shell, here is the code that illustrates it:

`. `

```
 # WRONG!
 true && { echo true; false; } || { echo false; true; }
```

Output is two lines "true" and "false", instead the single line "true".

&lt;&lt;Anchor(pf23)&gt;&gt;

## echo "Hello World!"

The problem here is that, in an interactive Bash shell (in versions prior to 4.3), you'll see an error like:

`. `

```
 bash: !": event not found
```

This is because, in the default settings for an interactive shell, Bash performs csh-style history expansion using the exclamation point. This is **not** a problem in shell scripts; only in interactive shells.

Unfortunately, the obvious attempt to "fix" this won't work:

`. `

```
 $ echo "hi\!"
 hi\!
```

The easiest solution is unsetting the `histexpand` option: this can be done with `set +H` or `set +o histexpand`

`. Question: Why is playing with `histexpand` more apropriate than single quotes?`  
` . `*`I personally ran into this issue when I was manipulating song files, using commands like`*  
` `

```
mp3info -t "Don't Let It Show" ...
mp3info -t "Ah! Leah!" ...
```

` `*`Using single quotes is extremely inconvenient because of all the songs with apostrophes in their titles. Using double quotes ran into the history expansion issue. (And imagine a file that has both in its name. The quoting would be atrocious.) Since I never actually`*`use`*`history expansion, my personal preference was to turn it off in `~/.bashrc`.`*` -- GreyCat`

These solutions will work:

`. `

```
 echo 'Hello World!'
```

or

`. `

```
 set +H
 echo "Hello World!"
```

or

`. `

```
 histchars=
```

Many people simply choose to put `set +H` or `set +o histexpand` in their `~/.bashrc` to deactivate history expansion permanently. This is a personal preference, though, and you should choose whatever works best for you.

Another solution is:

`. `

```
 exmark='!'
 echo "Hello, world$exmark"
```

In Bash 4.3 and newer, a double quote following `!` no longer triggers history expansion, but history expansion is still performed within double quotes, so while `echo "Hello World!"` is OK, these will still be a problem:

`. `

```
 echo "Hello, World!(and the rest of the Universe)"
 echo "foo!'bar'"
```

&lt;&lt;Anchor(pf24)&gt;&gt;

## for arg in $\*

Bash (like all Bourne shells) has a special syntax for referring to the list of positional parameters one at a time, and `$\*` isn't it. Neither is `$@`. Both of those expand to the list of words in your script's parameters, not to each parameter as a separate word.

The correct syntax is:

`. `

```
 for arg in "$@"

 # Or simply:
 for arg
```

Since looping over the positional parameters is such a common thing to do in scripts, `for arg` defaults to `for arg in "$@"`. The double-quoted `"$@"` is special magic that causes each parameter to be used as a single word (or a single loop iteration). It's what you should be using at least 99% of the time.

Here's an example:

`. `

```
 # Incorrect version
 for x in $*; do
   echo "parameter: '$x'"
 done

 $ ./myscript 'arg 1' arg2 arg3
 parameter: 'arg'
 parameter: '1'
 parameter: 'arg2'
 parameter: 'arg3'
```

It should have been written:

`. `

```
 # Correct version
 for x in "$@"; do
   echo "parameter: '$x'"
 done
# or better:
 for x do
   echo "parameter: '$x'"
 done

 $ ./myscript 'arg 1' arg2 arg3
 parameter: 'arg 1'
 parameter: 'arg2'
 parameter: 'arg3'
```

&lt;&lt;Anchor(pf25)&gt;&gt;

## function foo()

This works in some shells, but not in others. You should *never* combine the keyword `function` with the parentheses `()` when defining a function.

Bash (at least some versions) will allow you to mix the two. Most of the shells won't accept that (zsh 4.x and perhaps above will - for example). Some shells will accept `function foo`, but for maximum portability, you should always use:

`. `

```
 foo() {
  ...
 }
```

&lt;&lt;Anchor(pf26)&gt;&gt;

## echo "~"

Tilde expansion only applies when '~' is unquoted. In this example echo writes '~' to stdout, rather than the path of the user's home directory.

Quoting path parameters that are expressed relative to a user's home directory should be done using $HOME rather than '~'. For instance consider the situation where $HOME is "/home/my photos".

`. `

```
 "~/dir with spaces" # expands to "~/dir with spaces"
 ~"/dir with spaces" # expands to "~/dir with spaces"
 ~/"dir with spaces" # expands to "/home/my photos/dir with spaces"
 "$HOME/dir with spaces" # expands to "/home/my photos/dir with spaces"
```

&lt;&lt;Anchor(pf27)&gt;&gt;

== local varname=$(command) == When declaring a local variable in a function, the `local` acts as a command in its own right. This can sometimes interact oddly with the rest of the line -- for example, if you wanted to capture the exit status (`$?`) of the CommandSubstitution, you can't do it. `local`'s exit status masks it.

It's best to use separate commands for this:

`. `

```
 local varname
 varname=$(command)
 rc=$?
```

This is also true of `export`, which will similarly mask the exit status.

The next pitfall describes another issue with this syntax:

&lt;&lt;Anchor(pf28)&gt;&gt;

== export foo=~/bar == [Tilde expansion](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/tildeexpansion) (with or without a username) is only guaranteed to occur when the tilde appears at the beginning of a [word](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/arguments), either by itself or followed by a slash. It is also guaranteed to occur when the tilde appears immediately after the `=` in an assignment.

However, the `export` and `local` commands *do not constitute an assignment*. So, in some shells (like Bash), `export foo=~/bar` will undergo tilde expansion; in others (like dash), it will not.

`. `

```
 foo=~/bar; export foo    # Right!
 export foo="$HOME/bar"   # Right!
```

&lt;&lt;Anchor(pf29)&gt;&gt;

## sed 's/$foo/good bye/'

In [single quotes](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/quotes), bash parameter expansions like `$foo` do not get expanded. That is the purpose of single quotes, to protect characters like `$` from the shell.

Change the quotes to double quotes:

`. `

```
 foo="hello"; sed "s/$foo/good bye/"
```

But keep in mind, if you use double quotes you might need to use more escapes. See the [Quotes](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/quotes)page.

&lt;&lt;Anchor(pf30)&gt;&gt;

## tr \[A-Z\] \[a-z\]

There are (at least) three things wrong here. The first problem is that `\[A-Z\]` and `\[a-z\]` are seen as [glob](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/glob)s by the shell. If you don't have any single-lettered filenames in your current directory, it'll seem like the command is correct; but if you do, things will go wrong. Probably at 0300 hours on a weekend.

The second problem is that this is not really the correct notation for `tr`. What this actually does is translate '\[' into '\['; anything in the range A-Z into a-z; and '\]' into '\]'. So you don't even need those brackets, and the first problem goes away.

The third problem is that depending on the [locale](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/locale), A-Z or a-z may not give you the 26 ASCII characters you were expecting. In fact, in some locales z is in the middle of the alphabet! The solution to this depends on what you want to happen:

`. `

```
 # Use this if you want to change the case of the 26 latin letters
 LC_COLLATE=C tr A-Z a-z

 # Use this if you want the case conversion to depend upon the locale, which might be more like what a user is expecting
 tr '[:upper:]' '[:lower:]'
```

The quotes are required on the second command, to avoid [globbing](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/glob).

&lt;&lt;Anchor(pf31)&gt;&gt;

## ps ax | grep gedit

The fundamental problem here is that the name of a running process is inherently unreliable. There could be more than one legitimate gedit process. There could be something else disguising itself as gedit (changing the reported name of an executed command is trivial). For *real* answers to this, see ProcessManagement.

The following is the quick and dirty stuff.

Searching for the PID of (for example) gedit, many people start with

```
$ ps ax | grep gedit
10530 ?        S      6:23 gedit
32118 pts/0    R+     0:00 grep gedit
```

which, depending on a RaceCondition, often yields grep itself as a result. To filter grep out:

```
ps ax | grep -v grep | grep gedit   # will work, but ugly
```

An alternative to this is to use:

```
ps ax | grep '[g]edit'              # quote to avoid shell GLOB
```

This will ignore the grep itself in the process table as that is \[g\]edit and grep is looking for gedit once evaluated.

On GNU/Linux, the parameter -C can be used instead to filter by commandname:

```
$ ps -C gedit
  PID TTY          TIME CMD
10530 ?        00:06:23 gedit
```

But why bother when you could just use pgrep instead?

```
$ pgrep gedit
10530
```

Now in a second step the PID is often extracted by awk or cut:

```
$ ps -C gedit | awk '{print $1}' | tail -n1
```

but even that can be handled by some of the trillions of parameters for ps:

```
$ ps -C gedit -opid=
10530
```

If you're stuck in 1992 and aren't using pgrep, you could use the ancient, obsolete, deprecated pidof (GNU/Linux only) instead:

```
$ pidof gedit
10530
```

and if you need the PID to kill the process, *pkill* might be interesting for you. Note however that, for example, `pgrep/pkill ssh` would also find processes named sshd, and you wouldn't want to kill those.

Unfortunately some programs aren't started with their name, for example firefox is often started as firefox-bin, which you would need to find out with - well - **ps ax | grep firefox**. :) Or, you can stick with pgrep by adding some parameters:

```
$ pgrep -fl firefox
3128 /usr/lib/firefox/firefox
7120 /usr/lib/firefox/plugin-container /usr/lib/flashplugin-installer/libflashplayer.so -greomni /usr/lib/firefox/omni.ja 3128 true plugin
```

Please read ProcessManagement. Seriously.

&lt;&lt;Anchor(pf32)&gt;&gt;

## printf "$foo"

This isn't wrong because of [quotes](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/quotes), but because of a *format string exploit*. If `$foo` is not strictly under your control, then any `\\` or `%` characters in the variable may cause undesired behavior.

Always supply your own format string:

```
printf %s "$foo"
printf '%s\n' "$foo"
```

&lt;&lt;Anchor(pf33)&gt;&gt;

## for i in {1..$n}

The BashParser performs BraceExpansion *before* any other expansions or substitutions. So the brace expansion code sees the literal `$n`, which is not numeric, and therefore it doesn't expand the curly braces into a list of numbers. This makes it nearly impossible to use brace expansion to create lists whose size is only known at run-time.

Do this instead:

```
for ((i=1; i<=n; i++)); do
...
done
```

In the case of simple iteration over integers, an arithmetic `for` loop should almost always be preferred over brace expansion to begin with, because brace expansion pre-expands every argument which can be slower and unnecessarily consumes memory.

&lt;&lt;Anchor(pf34)&gt;&gt;

## if [$foo = $bar](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/foo-bar) (depending on intent)

When the right-hand side of an `=` operator inside \[\[BashFAQ/031|[](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/)is not quoted, bash does [pattern matching](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/glob) against it, instead of treating it as a string. So, in the code above, if `bar` contains `\*`, the result will *always* be true. If you want to check for equality of strings, the right-hand side should be quoted:

```
if [[ $foo = "$bar" ]]
```

If you want to do pattern matching, it might be wise to choose variable names that indicate the right-hand side contains a pattern. Or use comments.

It's also worth pointing out that if you quote the right-hand side of `=~` it *also* forces a simple string comparison, rather than a regular expression matching. This leads us to:

&lt;&lt;Anchor(pf35)&gt;&gt;

## if [$foo =~ 'some RE'](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/foo-some-re)

The quotes around the right-hand side of the `=~` operator cause it to become a string, rather than a RegularExpression. If you want to use a long or complicated regular expression and avoid lots of backslash escaping, put it in a variable:

```
re='some RE'
if [[ $foo =~ $re ]]
```

This also works around the difference in how `=~` works across different versions of bash. Using a variable avoids some nasty and subtle problems.

The same problem occurs with [pattern matching](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/glob) inside `[`: &lt;pre&gt; \[\[ $foo = "\*.glob"](`:_<pre>_[[_$foo_=_"*.glob" "wikilink") # Wrong! \*.glob is treated as a literal string. [$foo = \*.glob]($foo_=_*.glob "wikilink") # Correct. \*.glob is treated as a glob-style pattern.

&lt;&lt;Anchor(pf36)&gt;&gt;

## \[ -n $foo \] or \[ -z $foo \]

When using the `\[` command, you **must** [quote](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/quotes)each substitution that you give it. Otherwise, `$foo` could expand to 0 words, or 42 words, or any number of words that isn't 1, which breaks the syntax.

```
[ -n "$foo" ]
[ -z "$foo" ]
[ -n "$(some command with a "$file" in it)" ]

# [[ doesn't perform word-splitting or glob expansion, so you could also use:
[[ -n $foo ]]
[[ -z $foo ]]
```

&lt;&lt;Anchor(pf37)&gt;&gt;

## [-e "$broken\_symlink"](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/-e-broken-symlink) returns 1 even though $broken\_symlink exists

Test follows symlinks, therefore if a symlink is broken, i.e. it points to a file that doesn't exists or is in a directory you don't have access to, test -e returns 1 for it even though it exists.

In order to work around it (and prepare against it) you should use:

```
# bash/ksh/zsh
[[ -e "$broken_symlink" || -L "$broken_symlink" ]]

# POSIX sh+test
[ -e "$broken_symlink" ] || [ -L "$broken_symlink" ]
```

&lt;&lt;Anchor(pf38)&gt;&gt;

## ed file &lt;&lt;&lt;"g/d\\{0,3\\}/s//e/g" fails

The problem caused because ed doesn't accept 0 for \\{0,3\\}.

You can check that the following do work:

```
ed file <<<"g/d\{1,3\}/s//e/g"
```

Note that this happens even though POSIX states that BRE (which is the Regular Expression flavor used by ed) [should accept 0 as the minimum number of occurrences (see section 5)](http://www.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03_06 "wikilink").

&lt;&lt;Anchor(pf39)&gt;&gt;

## expr sub-string fails for "match"

This works reasonably well

---

most of the time

```
word=abcde
expr "$word" : ".\(.*\)"
bcde
```

But WILL fail for the word "match"

```
word=match
expr "$word" : ".\(.*\)"
```

The problem is "match" is a keyword. Solution (GNU only) is prefix with a '+'

```
word=match
expr + "$word" : ".\(.*\)"
atch
```

Or, y'know, stop using `expr`. You can do everything `expr` does by using [Parameter Expansion](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/bashfaq073). What's that thing up there trying to do? Remove the first letter of a word? That can be done in POSIX shells using PE or Substring Expansion:

```
$ word=match
$ echo "${word#?}"    # PE
atch
$ echo "${word:1}"    # SE
atch
```

Seriously, there's no excuse for using `expr` unless you're on Solaris with its non-POSIX-conforming `/bin/sh`. It's an external process, so it's much slower than in-process string manipulation. And since nobody uses it, nobody understands what it's doing, so your code is obfuscated and hard to maintain.

&lt;&lt;Anchor(pf40)&gt;&gt;

## On UTF-8 and Byte-Order Marks (BOM)

**In general:** Unix UTF-8 text does not use BOM. The encoding of plain text is determined by the locale or by mime types or other metadata. While the presence of a BOM would not normally damage a UTF-8 document meant only for reading by humans, it is problematic (often syntactically illegal) in any text file meant to be interpreted by automated processes such as scripts, source code, configuration files, and so on. Files starting with BOM should be considered equally foreign as those with MS-DOS linebreaks.

**In shell scripting:** 'Where UTF-8 is used transparently in 8-bit environments, the use of a BOM will interfere with any protocol or file format that expects specific ASCII characters at the beginning, such as the use of "#!" of at the beginning of Unix shell scripts.' [http://unicode.org/faq/utf\_bom.html#bom5](http://unicode.org/faq/utf_bom.html#bom5)

&lt;&lt;Anchor(pf41)&gt;&gt;

== content=$(&lt;file) == There isn't anything wrong with this expression, but you should be aware that command substitutions (all forms:

```
`...`
```

, `$(...)`, `$(&lt;file)`,

```
`<file`
```

, and `${ ...; }` (ksh)) remove any trailing newlines. This is often inconsequential or even desirable, but if you must preserve the literal output including any possible trailing newlines, it gets tricky because you have no way of knowing whether the output had them or how many. One ugly but usable workaround is to add a postfix inside the command substitution and remove it on the outside:

```
absolute_dir_path_x=$(readlink -fn -- "$dir_path"; printf x)
absolute_dir_path=${absolute_dir_path_x%x}
```

A less portable but arguably prettier solution is to use `read` with an empty delimiter.

```
# Ksh (or bash 4.2+ with lastpipe enabled)
readlink -fn -- "$dir_path" | IFS= read -rd '' absolute_dir_path
```

The downside to this method is that the `read` will always return false unless the command outputs a NUL byte causing only part of the stream to be read. The only way to get the exit status of the command is through `PIPESTATUS`. You could also intentionally output a NUL byte to force `read` to return true, and use `pipefail`.

```
set -o pipefail
{ readlink -fn -- "$dir_path"; printf '\0x'; } | IFS= read -rd '' absolute_dir_path
```

This is somewhat of a portability mess, as Bash supports both `pipefail` and `PIPESTATUS`, ksh93 supports `pipefail` only, and only recent versions of mksh support `pipefail`, while earlier versions supported `PIPESTATUS` only. Additionally, a bleeding-edge ksh93 version is required in order for `read` to stop at the NUL byte.

&lt;&lt;Anchor(pf42)&gt;&gt;

## for file in ./\* ; do if [$file != \*.\*](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/file-)

One way to prevent programs from interpreting filenames passed to them as options is to use pathnames (see [pitfall #3](#pf3 "wikilink") above). For files under the current directory, names may be prefixed with a relative pathname `./`.

In the case of a pattern like `\*.\*` however, problems can arise because it matches a string of the form `./filename`. In a simple case, you can just use the glob directly to generate the desired matches. If however a separate pattern-matching step is required (e.g. the results have been preprocessed and stored in an array, and need to be filtered), it could be solved by taking the prefix into account in the pattern: `[$file != ./\*.\*](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/file-)`, or by stripping the pattern from the match.

```
# Bash
shopt -s nullglob
for path in ./*; do
    [[ ${path##*/} != *.* ]] && rm "$path"
done

# Or even better
for file in *; do
    [[ $file != *.* ]] && rm "./$file"
done

# Or better still
for file in *.*; do
    rm "./$file"
done
```

Another possibility is to signal the *end of options* with a `--` argument. (Again, covered in [\#pf3](#pf3 "wikilink")).

```
shopt -s nullglob
for file in *; do
    [[ $file != *.* ]] && rm -- "$file"
done
```

&lt;&lt;Anchor(pf43)&gt;&gt;

## somecmd 2&gt;&amp;1 &gt;&gt;logfile

This is by far the most common mistake involving redirections, typically performed by someone wanting to direct both stdout and stderr to a file or pipe will try this and not understand why stderr is still showing up on their terminal. If you're perplexed by this, you probably don't understand how [redirections](http://wiki.bash-hackers.org/howto/redirection_tutorial "wikilink") or possibly [file descriptors](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/filedescriptor) work to begin with. Redirections are evaluated left-to-right before the command is executed. This semantically incorrect code essentially means: "first redirect standard error to where standard out is currently pointing (the tty), then redirect standard out to logfile". This is backwards. Standard error is already going to the tty. Use the following instead:

```
somecmd >>logfile 2>&1
```

See [a more in-depth explanation](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/bashfaq055), [Copy descriptor explained](http://wiki.bash-hackers.org/scripting/copydescriptor "wikilink"), and [BashGuide - redirection](BashGuide/InputAndOutput#Redirection "wikilink").

&lt;&lt;Anchor(pf44)&gt;&gt;

## cmd; (( ! $? )) || die

`$?` is only required if you need to retrieve the exact status of the previous command. If you only need to test for success or failure (any non-zero status), just test the command directly. e.g.:

```
if cmd; then
    ...
fi
```

Checking an exit status against a list of alternatives might follow a pattern like this:

```
cmd
status=$?
case $status in
    0)
        echo success >&2
        ;;
    1)
        echo 'Must supply a parameter, exiting.' >&2
        exit 1
        ;;
    *)
        echo "Unknown error $status, exiting." >&2
        exit "$status"
esac
```

&lt;&lt;Anchor(pf45)&gt;&gt;

== y=$(( array\[$x\] )) == Due to [the POSIX wording](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_04 "wikilink") of arithmetic expansion (which calls for expansion of command substitutions *after* parameter expansion), expansion of an array subscript inside an arithmetic expansion can lead to code injection exploits.

Yeah, that's a lot of big, confusing words. Here's how it breaks:

```
$ x='$(date >&2)'        # redirection is just so we can see everything happen
$ y=$((array[$x]))       # array doesn't even have to exist
Mon Jun  2 10:49:08 EDT 2014
```

Quoting `"$x"` won't help, either:

```
$ y=$((array["$x"]))
Mon Jun  2 10:51:03 EDT 2014
```

The two tricks that *do* work are:

```
# 1. Escape the $x so it isn't expanded prematurely.
$ y=$((array[\$x]))

# 2. Use the full ${array[$x]} syntax.
$ y=$((${array[$x]}))
```

&lt;&lt;Anchor(pf46)&gt;&gt;

## read num; echo $((num+1))

Always validate your input (see [BashFAQ/054](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/bashfaq054)) before using num in an arithmetic context as it allows code injection.

```
$ echo 'a[$(echo injection >&2)]' | bash -c 'read num; echo $((num+1))'
injection
1
```

&lt;&lt;Anchor(pf47)&gt;&gt;

== IFS=, read -ra fields &lt;&lt;&lt; "$csv\_line" == Unbelievable as it may seem, POSIX requires the treatment of [IFS](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/ifs)as a field *terminator*, rather than a field *separator*. What this means in our example is that if there's an empty field at the end of the input line, it will be discarded:

```
$ IFS=, read -ra fields <<< "a,b,"
$ declare -p fields
declare -a fields='([0]="a" [1]="b")'
```

Where did the empty field go? It was eaten for historical reasons ("because it's always been that way"). This behavior is not unique to bash; all conformant shells do it. A non-empty field is properly scanned:

```
$ IFS=, read -ra fields <<< "a,b,c"
$ declare -p fields
declare -a fields='([0]="a" [1]="b" [2]="c")'
```

So, how do we work around this nonsense? As it turns out, appending an IFS character to the end of the input string will force the scanning to work. If there was a trailing empty field, the extra IFS character "terminates" it so that it gets scanned. If there was a trailing non-empty field, the IFS character creates a new, empty field that gets dropped.

```
$ input="a,b,"
$ IFS=, read -ra fields <<< "$input,"
$ declare -p fields
declare -a fields='([0]="a" [1]="b" [2]="")'
```

&lt;&lt;Anchor(pf48)&gt;&gt;

== export CDPATH=.:~/myProject == Do not export CDPATH.

Setting CDPATH in .bashrc is not an issue, but exporting it will cause any bash or sh script you run, that happen to use `cd`, to potentially change behaviour.

There are two problems. A script that does the following:

```
cd some/dir || exit
cmd to be run in some/dir
```

may change directory to `~/myProject/some/dir` instead of `./some/dir`, depending on what directories exist at the time. So the `cd` may succeed and take the script to the wrong directory, with potentially harmful effects of the following commands which now run in a different directory than intended.

The second problem is when `cd` is run in a context where the output is captured:

```
output=$(cd some/dir && some command)
```

As a side-effect when CDPATH is set, `cd` will output something like `/home/user/some/dir` to stdout to indicate that it found a directory through CDPATH, which in turn will end up in the output variable along with the intended output of `some command`.

A script can make itself immune to a CDPATH inherited from the environment by always prepending `./` to relative paths, or run `unset CDPATH` at the start of the script, but don't assume every scripter has taken this pitfall into account, so don't export CDPATH.

&lt;&lt;Anchor(pf49)&gt;&gt;

== OIFS="$IFS"; ...; IFS="$OIFS" == Directly assigning a variable's value to a temporary variable isn't alone enough to restore its state. The assignment will always result in a *set* but *empty*temporary variable even if the initial variable was unset. This is a particular problem for IFS because an *empty* IFS has a completely different meaning from an *unset* IFS, and setting IFS to a temporary value for a command or two is a common requirement.

An easy workaround is to designate a prefix to distinguish set from unset vars, then strip it when finished.

```
# oIFS is unset or null implies IFS is null.

typeset oIFS=${IFS+_${IFS}}
IFS=/; echo "${array[*]}"
${oIFS:+'false'} unset -v IFS || IFS=${oIFS#_}
```

A local variable is usually preferable when possible.

```
f() {
  local IFS
  IFS=/; echo "${array[*]}"
}
f
```

Subshells are another possibility.

```
( IFS=/; echo "${array[*]}" )
```

&lt;&lt;Anchor(pf50)&gt;&gt;

== hosts=( $(aws ...) ) == It is not safe to populate an array with a raw `$(...)` CommandSubstitution. The output of the command undergoes word splitting (on *all* whitespace, even ones that are inside quotes) and then [globbing](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/glob). If there's a word like `\*` or `eh?` or `\[abc\]` in the result, it will be expanded based on filenames in the current working directory.

To select a replacement, you need to know whether the command writes its output on a single line, or multiple lines. If it's a single line:

```
read -ra hosts < <(aws ...)
```

If it's multiple lines (and you're targeting bash 4.0 or later):

```
readarray -t hosts < <(aws ...)
```

If it's multiple lines (and you want compatibility with bash 3.x, *or* want your command's exit status to be reflected in success or failure of the `read` operation without depending on behavior only available in bash 4.4 and newer):

```
IFS=$'\n' read -r -d '' -a hosts < <(aws ... && printf '\0')
```

This will prevent globbing. It still won't help you if you needed to avoid splitting on quoted whitespace, but unfortunately *nothing*bash can do handles that case. For generalized CSV (comma-separated value) file handling, you really need to switch to a language that has a dedicated CSV input library.

&lt;&lt;Anchor(pf51)&gt;&gt;

## Non-atomic writes with xargs -P

GNU `xargs` supports running multiple jobs in parallel. `-P n` where **n** is the number of jobs to run in parallel.

```
seq 100 | xargs -n1 -P10 echo "$a" | grep 5
seq 100 | xargs -n1 -P10 echo "$a" > myoutput.txt
```

This will work fine for many situations but has a deceptive flaw: If `$a` contains more than ~1000 characters, the `echo` may not be atomic (it may be split into multiple `write()` calls), and there is a risk that two lines will be mixed.

```
$ perl -e 'print "a"x2000, "\n"' > foo
$ strace -e write bash -c 'read -r foo < foo; echo "$foo"' >/dev/null
write(1, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"..., 1008) = 1008
write(1, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"..., 993) = 993
+++ exited with 0 +++
```

Obviously the same issue arises if there are multiple calls to `echo` or `printf`:

```
slowprint() {
  printf 'Start-%s ' "$1"
  sleep "$1"
  printf '%s-End\n' "$1"
}
export -f slowprint
seq 10 | xargs -n1 -I {} -P4 bash -c "slowprint {}"
# Compare to no parallelization
seq 10 | xargs -n1 -I {} bash -c "slowprint {}"
# Be sure to see the warnings in the next Pitfall!
```

Outputs from the parallel jobs are mixed together, because each job consists of two (or more) separate `write()` calls.

If you need the outputs unmixed, it is therefore recommended to use a tool that guarantees output will be serialized (such as GNU Parallel).

For further details see [a demonstration of the mixing problem](https://gist.github.com/ole-tange/88ae153797748b3618e2433377e2870a "wikilink").

&lt;&lt;Anchor(pf52)&gt;&gt;

## find . -exec sh -c 'echo {}' \\;

This command contains a CodeInjection vulnerability. The filename that is found by `find` is injected into a shell command and parsed by `sh`. If the filename contains shell metacharacters like `;` or `$( ... )` then the filename may be *executed as code* by `sh'.

The "slowprint" example in the previous Pitfall would have been a CodeInjection bug if the input weren't guaranteed to be integers.

To be more precise, [POSIX find](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/find.html#tag_20_47 "wikilink") does not specify whether an argument which contains *more than* just `{}` is expanded. GNU `find` allows this CodeInjection to occur. Other implementations choose a safer path:

```
# uname -a
HP-UX imadev B.10.20 A 9000/785 2008897791 two-user license
# find /dev/null -exec sh -c 'echo {}' \;
{}
```

The correct approach is to *separate* the filename argument from the script argument:

```
find . -exec sh -c 'echo "$1"' x {} \;
```

&lt;&lt;Anchor(pf53)&gt;&gt;

## sudo mycmd &gt; /myfile

[Redirection](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/redirection)is done *before* the command is executed. Usually that doesn't matter, but with `sudo` we have a command being executed as a different user than the redirection.

If the redirection must be executed with `sudo`-granted privileges, then you need a wrapper:

```
sudo sh -c 'mycmd > /myfile'
```

&lt;&lt;Anchor(pf54)&gt;&gt;

## sudo ls /foo/\*

This is very similar to the previous pitfall. [Globbing](https://www.reeltoreel.nl/knowledgebase/books/mediawiki-import/page/glob)is also done *before* the command is executed. If the directory isn't readable by your normal user privileges, then you may need the globbing to be done in a shell that has the `sudo`-granted privileges:

```
sudo sh -c 'ls /foo/*'
```

&lt;&lt;Anchor(pf55)&gt;&gt;

## myprogram 2&gt;&amp;-

**Do not** close stdin, stdout or stderr as a "shorthand" for redirecting to `/dev/null`. Write it out correctly.

```
myprogram 2>/dev/null
```

Why? Consider what happens when your program tries to write an error message to stderr. If stderr has been redirected to `/dev/null`, the write succeeds, and your program is free to carry on, secure in the knowledge that it has diligently reported the error condition.

But if stderr has been *closed*, then the write will fail. At that point, your program may do something unpredictable. It may carry on and ignore the failure, or it may immediately exit, considering the execution environment so broken that it cannot safely continue. Or whatever else the programmer decided the program should do when its world has become a dystopian hell.

All programs are assured that stdin, stdout and stderr will *exist* and will be readable/writable in an appropriate and reasonable manner. By closing one of them, you have violated your promise to this program. This is not acceptable.

Of course, an even better solution would be to actually log the errors somewhere, so you can go back and read them and figure out what's wrong.

&lt;&lt;Anchor(pf56)&gt;&gt;

## Using xargs without -0

`xargs` splits on whitespace. This is unfortunate because whitespace is allowed in filenames and commonly used by GUI users. `xargs` also treats `'` and `"` specially, which can also lead to problems:

```
touch Dad\'s\ \"famous\"\ 1\'\ pizza.txt
touch Dad\'s\ 12\"\ records.txt
touch 2\"x1\'\ wood.txt
touch 2\"x4\"\ wood.txt
```

Here `xargs` warns:

```
# Do not do this
$ find . -type f | xargs wc
xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option
```

Here `xargs` does not warn at all:

```
# Do not do this
echo * | xargs wc
find *famous* -type f | xargs wc
find *4* -type f | xargs wc
```

Instead use `xargs -0`:

```
# Do this instead
printf '%s\0' * | xargs -0 wc
find . -type f -name '*famous*' -print0 | xargs -0 wc
find . -type f -name '*4*' -exec wc {} +
```

If using `-0` is not simple, an alternative is to use GNU Parallel, which splits on \\n. And while \\n is also allowed in filenames they never occur unless your users are malicious. In any case: **If**you use `xargs` without `-0` put a comment in your code explaining why that is safe in your particular situation.

---

CategoryShell CategoryBashguide

# File permissions

## File permissions

One of the important things you can do to help secure your MediaWiki install, is ensure that the user you are running php as (often www-data if using debian) and the user you are running mysql as, does not have write access to any web accessible directory with php enabled.

- On unix-like systems, you can do this by ensuring that the mediawiki directory/files are owned by someone other than your web server user (www-data) or mysql server user. Depending on how you installed MediaWiki this may already be the case, but if not can be accomplished by doing `chown -R `<usernamehere>` /path/to/MediaWiki/`where username is a user other than the webserver or mysql user (commonly you would use your own username provided mysql&lt;/&gt; and php are not running as your username).</usernamehere>

- **After doing that step, you may however need to change the owner of the image directory back to the php user,** as uploaded files need to go there, so MediaWiki needs to be able to write there (e.g. `chown -R www-data /path/to/MediaWiki/images`).
- Next you run `chmod -R go-w /path/to/MediaWiki` to remove write access from all other users besides the file owners.
- After doing that step you may need to re-enable write access to the images directory.

- Directories that MediaWiki needs write access to (such as $wgCacheDirectory if that feature is enabled) should be located outside of the web root. The exception being the images directory, which must be in the web root.
- However, it is important to disable php in the images directory. The details on how to do this varies with webserver, but on apache it can sometimes be accomplished by using `php_flag engine off` in a .htaccess&lt;/&gt; file. If you do accomplish this via a config file in the images directory itself, you should ensure the config file is not writable by the webserver. See the section below on upload security for more details.

- Your LocalSettings.php file must be readable by the php user, however it should not be world readable, to prevent other processes from discovering your database password and other sensitive information. Like all MediaWiki files, the php user should not be able to write to LocalSettings.php.

## permissions

New install of MediaWiki 1.28 on Ubuntu 16.04. Permissions for /var/www/html set to 755, owned by me user:www-data.

Did a Download from Git install, before and after doing composer install, the file and directory permissions are readable and writable but not executable for group. Should I set them to 755 manually?

In your MediaWiki directory, the following SSH commands should work:

`find . -type f -exec chmod 644 {} \;`  
`find . -type d -exec chmod 755 {} \;`

## securing

The following picks up on a fresh working LAMP installation under Red Hat 7 or clone (CentOS 7, Scientific Linux 7, Orcale 7, etc). Set Selinux to permissive for the installation.

`   setenforce 0`

First get the Mediawiki version you want from [https://releases.wikimedia.org/mediawiki/](https://releases.wikimedia.org/mediawiki/), at time of writing latest is [https://releases.wikimedia.org/mediawiki/1.27/mediawiki-1.27.0.tar.gz](https://releases.wikimedia.org/mediawiki/1.27/mediawiki-1.27.0.tar.gz)and unpack it in /var/www/html/w.

Navigate to [https://www.example.com/w](https://www.example.com/w) and follow on-screen instructions to generate content used for LocalSettings.php. Create LocalSettings.php with

`   vi /var/www/html/w/LocalSettings.php`

and paste content into file (<kbd>i</kbd> -&gt; enter insert mode, <kbd>CTRL</kbd>+<kbd>SHIFT</kbd>+<kbd>v</kbd> to paste content, <kbd>ESC</kbd> -&gt; to exit insert mode, <kbd>Z</kbd><kbd>Z</kbd>(twice letter Z) to save and exit vi). Now secure LocalSettings.php with

`   chown root:apache /var/www/html/w/LocalSettings.php`  
`   chmod 640 /var/www/html/w/LocalSettings.php`

Delete mw-config if it exists, since it is only used for first time setup of mediawiki.

`   rm -rf /var/www/html/w/mw-config`

Enable use of .htaccess files by creating custom configuration file for Apache httpd.

`   cat >> /etc/httpd/conf.d/custom.conf << EOF`  
`   <Directory "/var/www/html/w">`  
`    AllowOverride All`  
`   `  
`   EOF`

Now one should customize LocalSettings.php to one's taste. Here an overview of variables that can be customized: [https://www.mediawiki.org/wiki/Manual:Configuration\_settings](https://www.mediawiki.org/wiki/Manual:Configuration_settings)

Since we want to access our Mediawiki installation under [https://www.example.com/wiki](https://www.example.com/wiki) we need to set $wgArticlePath in LocalSettings.php. Just add the following line a the bottom of LocalSettings.php

`   $wgArticlePath = "/wiki/$1";`

and update /etc/httpd/conf.d/ssl.conf by adding one line.

`   <VirtualHost _default_:443>`  
`   Alias /wiki /var/www/html/w/index.php  # <-- only add this line`

### selinux

Now finish securing the Mediawiki installation. This \*may\* be needed for Selinux, e.g. database on different server, etc.

`   setsebool -P httpd_can_network_connect 1`  
`   setsebool -P httpd_can_network_connect_db 1`

This \*is\* needed for Selinux to run Mediawiki

`   setsebool -P httpd_builtin_scripting 1`  
`   setsebool -P httpd_execmem 1`

Set userrights and special Selinux rights, so Apache httpd has read access, but other users beside root don't.

`   chown -R root:apache /var/www/html/`  
`   find /var/www/html/w -type d -exec chmod 750 {} \;`  
`   find /var/www/html/w -type f -exec chmod 640 {} \;`

Mediawiki writes to images and cache, so they need special write premissions.

`   chown -R apache:apache /var/www/html/w/images`  
`   chown -R apache:apache /var/www/html/w/cache`  
`   semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/w/cache(/.*)?"`  
`   semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/w/images(/.*)?"`  
`   restorecon -R /var/www/html/w`

Found Selinux complaining about hugetlbfs, so add an exception.

`   cd /var/log/audit`  
`   grep hugetlbfs audit.log | audit2allow -M hugetlbfs`  
`   semodule -i hugetlbfs.pp`

Now restart Apache httpd and set Selinux back to enforcing.

`   setenforce 1`  
`   systemctl restart httpd`

Understandably this covers only the basics and Mediawiki offers thousands of ways to customize it further to one's taste and security needs.

Don't forget to make regular backups.

Further suggestions can be found here [https://www.pozzo-balbi.com/help/Mediawiki](https://www.pozzo-balbi.com/help/Mediawiki).

# Disable cpu core for light work

`# echo 0 | sudo tee /sys/bus/cpu/devices/cpu$COREID/online # Disable a CPU core to save battery and lower thermals. Works greats if your laptop is noisy and you're only doing light work`

# Rescan SCSI bus

`# echo "0 0 0" > /sys/class/scsi_host/host5/scan`

5 is changeable; it is the connection

# How to send email from command line in fixed font

To send email that is in fixed font you can use:

```
 # (echo "Subject: bla"; echo "MIME-Version: 1.0"; echo "Content-Type: text/html"; echo "Content-Disposition: inline"; echo '<html><body>The code element<SLASHpre></body></html>') |  sendmail joop@hotmail.com
```

Mind the /pre here.

</body></html>

# Rsync root volume

`# rsync -aAXv --exclude 'data' --exclude 'mnt' --exclude 'proc' --exclude 'sys' --exclude 'dev' --exclude 'run' /* /mnt/mmcblk/3/`

# Edit PDF metadata

View PDF metadata:

`# exiftool file.pdf`

View specific metadata:

`# exiftool -Creator file.pdf`  
`# find . -type f -iname '*.pdf' -exec exiftool -Creator {} \;`

Set metadata:

`# exiftool -Creator='barbapappa' file.pdf`  
`# find . -type f -iname '*.pdf' -exec exiftool -Creator='barbapappa' {} \;`

to preserve date/time:

`-P`

to delete backup file that is created:

`-delete_original[!]`

`# find . -type f -iname '*.pdf' -exec exiftool -P -overwrite_original -Producer='www.bladiebla.nl' -Creator='barbapappa' {} \;`  
`# find . -type f -iname '*.pdf' -exec exiftool -P -delete_original! {} \;`

# Edit in one metadatafile

Make a parameter file

```
-Title=Mijn Titel
-Author=Mijn Naam
-Creator=Microsoft Word
-Producer=Adobe PDF Library 15.0
-Subject=Korte samenvatting
-Keywords=tag1, tag2, tag3
-CreateDate=2025:08:14 08:00:00
-ModifyDate=2025:08:14 08:00:00
```

and apply with:

`# exiftool -@ meta.args -overwrite_original pdfbestand.pdf`

# workflow

```
#!/bin/bash
set -e

echo  alle odg naar pdf zetten
libreoffice --headless --convert-to pdf *.odg

echo alle pdf files in 1 groot document
pdfunite {1..22}.pdf samengevoegd.pdf

echo pdftk om fouten weg te krijgen
pdftk samengevoegd.pdf output rc1.pdf

echo de metadata erin
exiftool -@ metadata.csv rc1.pdf

echo haal oude metadata weg en houd alleen de laatste huidige
qpdf --linearize rc1.pdf rc2.pdf

echo
echo De file rc.2 is de output
echo
```

# Rsync root volume to new harddisk

`# rsync -aAXvx --progress --exclude='.snapshots/' / [mountpoint of new harddisk]`

# Exiftool

To fix the date time on the pixel 6a photo and video files, use for photos:

`# exiftool '-FileName<DateTimeOriginal' -d '%Y%m%d_%H%M%S%%-c.%%e' *.jpg`

and for video files: (NOT ENTIRELY CORRECT NEEDS UPDATING!!)

`# exiftool '-FileName<FileModifyDate' -d '%Y%m%d_%H%M%S%%-c.%%e' *.mp4`

# Lsmod

```
lsmod
Module                  Size  Used by
fuse                  106496  1
tcp_diag               16384  0
inet_diag              20480  1 tcp_diag
xt_CHECKSUM            16384  1
iptable_mangle         16384  1
ipt_MASQUERADE         16384  3
nf_nat_masquerade_ipv4    16384  1 ipt_MASQUERADE
iptable_nat            16384  1
nf_nat_ipv4            16384  1 iptable_nat
nf_nat                 24576  2 nf_nat_ipv4,nf_nat_masquerade_ipv4
tun                    32768  1
br_netfilter           24576  0
bridge                139264  1 br_netfilter
stp                    16384  1 bridge
llc                    16384  2 stp,bridge
ebtable_filter         16384  0
ebtables               36864  1 ebtable_filter
nf_log_ipv6            16384  20
xt_comment             16384  26
nf_log_ipv4            16384  20
nf_log_common          16384  2 nf_log_ipv4,nf_log_ipv6
xt_LOG                 16384  40
xt_limit               16384  40
af_packet              45056  0
iscsi_ibft             16384  0
iscsi_boot_sysfs       20480  1 iscsi_ibft
ip6t_REJECT            16384  3
nf_reject_ipv6         16384  1 ip6t_REJECT
nf_conntrack_ipv6      20480  9
nf_defrag_ipv6         36864  1 nf_conntrack_ipv6
ipt_REJECT             16384  5
nf_reject_ipv4         16384  1 ipt_REJECT
xt_pkttype             16384  7
xt_tcpudp              16384  84
iptable_filter         16384  1
ip6table_mangle        16384  0
nf_conntrack_netbios_ns    16384  0
nf_conntrack_broadcast    16384  1 nf_conntrack_netbios_ns
nf_conntrack_ipv4      16384  12
nf_defrag_ipv4         16384  1 nf_conntrack_ipv4
ip_tables              24576  3 iptable_filter,iptable_mangle,iptable_nat
xt_conntrack           16384  20
nf_conntrack          118784  8 nf_conntrack_netbios_ns,nf_nat,nf_nat_ipv4,xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_broadcast,nf_conntrack_ipv4,nf_conntrack_ipv6
ip6table_filter        16384  1
ip6_tables             28672  2 ip6table_filter,ip6table_mangle
x_tables               40960  17 xt_pkttype,ip6table_filter,ip6table_mangle,xt_comment,xt_CHECKSUM,ip_tables,xt_tcpudp,ipt_MASQUERADE,xt_limit,xt_conntrack,xt_LOG,iptable_filter,ebtables,ipt_REJECT,iptable_mangle,ip6_tables,ip6t_REJECT
msr                    16384  0
nct6775                61440  0
hwmon_vid              16384  1 nct6775
joydev                 20480  0
hid_logitech_hidpp     20480  0
xfs                  1085440  1
kvm_amd                86016  0
kvm                   610304  1 kvm_amd
raid456               147456  1
irqbypass              16384  1 kvm
async_raid6_recov      20480  1 raid456
async_memcpy           16384  2 raid456,async_raid6_recov
libcrc32c              16384  2 xfs,raid456
crct10dif_pclmul       16384  0
async_pq               16384  2 raid456,async_raid6_recov
async_xor              16384  3 async_pq,raid456,async_raid6_recov
crc32_pclmul           16384  0
xor                    20480  1 async_xor
crc32c_intel           24576  1
async_tx               16384  5 async_pq,raid456,async_xor,async_memcpy,async_raid6_recov
hid_logitech_dj        20480  0
ghash_clmulni_intel    16384  0
raid6_pq              118784  3 async_pq,raid456,async_raid6_recov
md_mod                155648  2 raid456
drbg                   28672  1
ansi_cprng             16384  0
usbhid                 53248  0
snd_usb_audio         188416  0
snd_usbmidi_lib        36864  1 snd_usb_audio
snd_hwdep              16384  1 snd_usb_audio
snd_rawmidi            36864  1 snd_usbmidi_lib
snd_seq_device         16384  1 snd_rawmidi
snd_pcm               135168  1 snd_usb_audio
aesni_intel           167936  0
aes_x86_64             20480  1 aesni_intel
lrw                    16384  1 aesni_intel
gf128mul               16384  1 lrw
glue_helper            16384  1 aesni_intel
ablk_helper            16384  1 aesni_intel
cryptd                 20480  3 ghash_clmulni_intel,aesni_intel,ablk_helper
snd_timer              36864  1 snd_pcm
snd                    90112  7 snd_usb_audio,snd_hwdep,snd_timer,snd_pcm,snd_rawmidi,snd_usbmidi_lib,snd_seq_device
'''r8169                  90112  0'''
soundcore              16384  1 snd
'''mii                    16384  1 r8169'''
i2c_piix4              24576  0
k10temp                16384  0
pcspkr                 16384  0
shpchp                 36864  0
acpi_cpufreq           20480  0
fjes                   32768  0
video                  45056  0
processor              49152  5 acpi_cpufreq
button                 16384  0
nfsd                  348160  9
auth_rpcgss            65536  1 nfsd
nfs_acl                16384  1 nfsd
lockd                 102400  1 nfsd
grace                  16384  2 nfsd,lockd
sunrpc                364544  13 nfsd,auth_rpcgss,lockd,nfs_acl
ext4                  651264  3
crc16                  16384  1 ext4
jbd2                  118784  1 ext4
mbcache                16384  4 ext4
sr_mod                 24576  0
cdrom                  61440  1 sr_mod
sd_mod                 57344  11
amdkfd                143360  1
amd_iommu_v2           20480  1 amdkfd
ohci_pci               16384  0
'''r8168                 540672  0'''
radeon               1597440  1
i2c_algo_bit           16384  1 radeon
drm_kms_helper        167936  1 radeon
syscopyarea            16384  1 drm_kms_helper
ahci                   40960  6
sysfillrect            16384  1 drm_kms_helper
sysimgblt              16384  1 drm_kms_helper
fb_sys_fops            16384  1 drm_kms_helper
libahci                36864  1 ahci
ttm                   110592  1 radeon
ohci_hcd               53248  1 ohci_pci
pata_atiixp            16384  2
ehci_pci               16384  0
xhci_pci               16384  0
ehci_hcd               81920  1 ehci_pci
xhci_hcd              192512  1 xhci_pci
usbcore               274432  9 snd_usb_audio,ohci_hcd,ohci_pci,snd_usbmidi_lib,ehci_hcd,ehci_pci,usbhid,xhci_hcd,xhci_pci
drm                   397312  4 ttm,drm_kms_helper,radeon
usb_common             16384  1 usbcore
ata_generic            16384  0
pata_amd               20480  0
libata                274432  5 ahci,libahci,pata_amd,ata_generic,pata_atiixp
sg                     49152  0
dm_multipath           32768  0
dm_mod                131072  1 dm_multipath
scsi_dh_rdac           20480  0
scsi_dh_emc            16384  0
scsi_dh_alua           20480  0
scsi_mod              253952  8 sg,scsi_dh_alua,scsi_dh_rdac,dm_multipath,scsi_dh_emc,libata,sd_mod,sr_mod
autofs4                45056  2
</nowiki>
```

# Lspci

```
lspci
00:00.0 Host bridge: Advanced Micro Devices, Inc. [AMD] Family 15h (Models 10h-1fh) Processor Root Complex
00:01.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Richland [Radeon HD 8570D]
00:05.0 PCI bridge: Advanced Micro Devices, Inc. [AMD] Family 15h (Models 10h-1fh) Processor Root Port
00:10.0 USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB XHCI Controller (rev 09)
00:10.1 USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB XHCI Controller (rev 09)
00:11.0 SATA controller: Advanced Micro Devices, Inc. [AMD] FCH SATA Controller [AHCI mode] (rev 40)
00:12.0 USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB OHCI Controller (rev 11)
00:12.2 USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB EHCI Controller (rev 11)
00:13.0 USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB OHCI Controller (rev 11)
00:13.2 USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB EHCI Controller (rev 11)
00:14.0 SMBus: Advanced Micro Devices, Inc. [AMD] FCH SMBus Controller (rev 16)
00:14.1 IDE interface: Advanced Micro Devices, Inc. [AMD] FCH IDE Controller
00:14.3 ISA bridge: Advanced Micro Devices, Inc. [AMD] FCH LPC Bridge (rev 11)
00:14.4 PCI bridge: Advanced Micro Devices, Inc. [AMD] FCH PCI Bridge (rev 40)
00:14.5 USB controller: Advanced Micro Devices, Inc. [AMD] FCH USB OHCI Controller (rev 11)
00:18.0 Host bridge: Advanced Micro Devices, Inc. [AMD] Family 15h (Models 10h-1fh) Processor Function 0
00:18.1 Host bridge: Advanced Micro Devices, Inc. [AMD] Family 15h (Models 10h-1fh) Processor Function 1
00:18.2 Host bridge: Advanced Micro Devices, Inc. [AMD] Family 15h (Models 10h-1fh) Processor Function 2
00:18.3 Host bridge: Advanced Micro Devices, Inc. [AMD] Family 15h (Models 10h-1fh) Processor Function 3
00:18.4 Host bridge: Advanced Micro Devices, Inc. [AMD] Family 15h (Models 10h-1fh) Processor Function 4
00:18.5 Host bridge: Advanced Micro Devices, Inc. [AMD] Family 15h (Models 10h-1fh) Processor Function 5
01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 11)
```

# Linux commandline tips 2

<table id="bkmrk-"><tbody><tr><td></td></tr></tbody></table>

<table id="bkmrk-command-%E2%80%A2-apropos-wh"><tbody><tr><td colspan="2">**Command**

</td></tr><tr><td>•

</td><td>apropos whatis

</td></tr><tr><td>•

</td><td>[man](http://www.pixelbeat.org/lkdb/less.html) -t man | ps2pdf - &gt; man.pdf

</td></tr><tr><td></td><td>which command

</td></tr><tr><td></td><td>time command

</td></tr><tr><td>•

</td><td>time cat

</td></tr><tr><td>•

</td><td>nice [info](http://www.pixelbeat.org/lkdb/info.html)

</td></tr><tr><td>•

</td><td>renice 19 -p $$

</td></tr><tr><td colspan="2">**dir navigation**

</td></tr><tr><td>•

</td><td>cd -

</td></tr><tr><td>•

</td><td>cd

</td></tr><tr><td></td><td>(cd dir &amp;&amp; command)

</td></tr><tr><td>•

</td><td>pushd **.**

</td></tr><tr><td colspan="2">**file searching**

</td></tr><tr><td>•

</td><td>[alias](http://www.pixelbeat.org/settings/.bashrc)l='ls -l --color=auto'

</td></tr><tr><td>•

</td><td>ls -lrt

</td></tr><tr><td>•

</td><td>ls /usr/bin | pr -T9 -W$COLUMNS

</td></tr><tr><td></td><td>find -name '\*.\[ch\]' | xargs grep -E 'expr'

</td></tr><tr><td></td><td>find -type f -print0 | xargs -r0 grep -F 'example'

</td></tr><tr><td></td><td>find -maxdepth 1 -type f | xargs grep -F 'example'

</td></tr><tr><td></td><td>find -maxdepth 1 -type d | while [read](http://www.pixelbeat.org/programming/readline/) dir; do echo $dir; echo cmd2; done

</td></tr><tr><td>•

</td><td>find -type f ! -perm -444

</td></tr><tr><td>•

</td><td>find -type d ! -perm -111

</td></tr><tr><td>•

</td><td>locate -r 'file\[^/\]\*\\.txt'

</td></tr><tr><td>•

</td><td>look reference

</td></tr><tr><td>•

</td><td>grep [--color](http://www.pixelbeat.org/settings/.bashrc) reference /usr/share/dict/words

</td></tr><tr><td colspan="2">**archives and compression**

</td></tr><tr><td></td><td>gpg -c file

</td></tr><tr><td></td><td>gpg file.gpg

</td></tr><tr><td></td><td>tar -c dir/ | bzip2 &gt; dir.tar.bz2

</td></tr><tr><td></td><td>bzip2 -dc dir.tar.bz2 | tar -x

</td></tr><tr><td></td><td>tar -c dir/ | gzip | gpg -c | ssh user@remote 'dd of=dir.tar.gz.gpg'

</td></tr><tr><td></td><td>find dir/ -name '\*.txt' | tar -c --files-from=- | bzip2 &gt; dir\_txt.tar.bz2

</td></tr><tr><td></td><td>find dir/ -name '\*.txt' | xargs cp -a --target-directory=dir\_txt/ --parents

</td></tr><tr><td></td><td>( tar -c /dir/to/copy ) | ( cd /where/to/ &amp;&amp; tar -x -p )

</td></tr><tr><td></td><td>( cd /dir/to/copy &amp;&amp; tar -c **.** ) | ( cd /where/to/ &amp;&amp; tar -x -p )

</td></tr><tr><td></td><td>( tar -c /dir/to/copy ) | ssh -C user@remote 'cd /where/to/ &amp;&amp; tar -x -p'

</td></tr><tr><td></td><td>dd bs=1M if=/dev/sda | gzip | ssh user@remote 'dd of=sda.gz'

</td></tr><tr><td colspan="2">**rsync** (Network efficient file copier: Use the --dry-run option for testing)

</td></tr><tr><td></td><td>rsync -P [rsync://rsync.server.com/path/to/file](rsync://rsync.server.com/path/to/file)file

</td></tr><tr><td></td><td>rsync --bwlimit=1000 fromfile tofile

</td></tr><tr><td></td><td>rsync -az -e ssh --delete ~/public\_html/ remote.com:'~/public\_html'

</td></tr><tr><td></td><td>rsync -auz -e ssh remote:/dir/ **.** &amp;&amp; rsync -auz -e ssh **.** remote:/dir/

</td></tr><tr><td colspan="2">**ssh** (Secure SHell)

</td></tr><tr><td></td><td>ssh $USER@$HOST command

</td></tr><tr><td>•

</td><td>ssh -f -Y $USER@$HOSTNAME xeyes

</td></tr><tr><td></td><td>scp -p -r $USER@$HOST: file dir/

</td></tr><tr><td></td><td>ssh -g -L 8080:localhost:80 root@$HOST

</td></tr><tr><td></td><td>ssh -R 1434:[imap:143](imap:143) root@$HOST

</td></tr><tr><td colspan="2">**wget** (multi purpose download tool)

</td></tr><tr><td>•

</td><td>(cd dir/ &amp;&amp; wget -nd -pHEKk [http://www.pixelbeat.org/cmdline.html](http://www.pixelbeat.org/cmdline.html))

</td></tr><tr><td></td><td>wget -c [http://www.example.com/large.file](http://www.example.com/large.file)

</td></tr><tr><td></td><td>wget -r -nd -np -l1 -A '\*.jpg' [http://www.example.com/dir/](http://www.example.com/dir/)

</td></tr><tr><td></td><td>wget ftp://remote/file\[1-9\].iso/

</td></tr><tr><td>•

</td><td>wget -q -O- [http://www.pixelbeat.org/timeline.html](http://www.pixelbeat.org/timeline.html)| grep 'a href' | head

</td></tr><tr><td></td><td>echo 'wget url' | at 01:00

</td></tr><tr><td></td><td>wget --limit-rate=20k url

</td></tr><tr><td></td><td>wget -nv --spider --force-html -i bookmarks.html

</td></tr><tr><td></td><td>wget --mirror [http://www.example.com/](http://www.example.com/)

</td></tr><tr><td colspan="2">**networking** (Note ifconfig, route, mii-tool, nslookup commands are obsolete)

</td></tr><tr><td></td><td>ethtool eth0

</td></tr><tr><td></td><td>ethtool --change eth0 autoneg off speed 100 duplex full

</td></tr><tr><td></td><td>iwconfig eth1

</td></tr><tr><td></td><td>iwconfig eth1 rate 1Mb/s fixed

</td></tr><tr><td>•

</td><td>iwlist scan

</td></tr><tr><td>•

</td><td>ip link show

</td></tr><tr><td></td><td>ip link set dev eth0 name wan

</td></tr><tr><td></td><td>ip link set dev eth0 up

</td></tr><tr><td>•

</td><td>ip addr show

</td></tr><tr><td></td><td>ip addr add 1.2.3.4/24 brd + dev eth0

</td></tr><tr><td>•

</td><td>ip route show

</td></tr><tr><td></td><td>ip route add default via 1.2.3.254

</td></tr><tr><td>•

</td><td>tc qdisc add dev lo root handle 1:0 netem delay 20msec

</td></tr><tr><td>•

</td><td>tc qdisc del dev lo root

</td></tr><tr><td>•

</td><td>host pixelbeat.org

</td></tr><tr><td>•

</td><td>hostname -i

</td></tr><tr><td>•

</td><td>whois pixelbeat.org

</td></tr><tr><td>•

</td><td>netstat -tupl

</td></tr><tr><td>•

</td><td>netstat -tup

</td></tr><tr><td colspan="2">**windows networking** (Note samba is the package that provides all this windows specific networking support)

</td></tr><tr><td>•

</td><td>smbtree

</td></tr><tr><td></td><td>nmblookup -A 1.2.3.4

</td></tr><tr><td></td><td>smbclient -L windows\_box

</td></tr><tr><td></td><td>mount -t smbfs -o fmask=666,guest //windows\_box/share /mnt/share

</td></tr><tr><td></td><td>echo 'message' | smbclient -M windows\_box

</td></tr><tr><td colspan="2">**text manipulation** (Note sed uses stdin and stdout. Newer versions support inplace editing with the -i option)

</td></tr><tr><td></td><td>sed 's/string1/string2/g'

</td></tr><tr><td></td><td>sed 's/<span class="math inline">.\*</span>1/\\12/g'

</td></tr><tr><td></td><td>sed '/ \*#/d; /^ \*$/d'

</td></tr><tr><td></td><td>sed ':a; /\\\\$/N; s/\\\\\\n//; ta'

</td></tr><tr><td></td><td>sed 's/\[ \\t\]\*$//'

</td></tr><tr><td></td><td>sed 's/\\(\[`"$\\\]\\)/\\\\\\1/g'

</td></tr><tr><td>•

</td><td>seq 10 | sed "s/^/ /; s/ \*<span class="math inline">.{7, }</span>/\\1/"

</td></tr><tr><td></td><td>sed -n '1000{p;q}'

</td></tr><tr><td></td><td>sed -n '10,20p;20q'

</td></tr><tr><td></td><td>sed -n 's/.\*&lt;title&gt;\\(.\*\\)&lt;\\/title&gt;.\*/\\1/ip;T;q'

</td></tr><tr><td></td><td>sed -i 42d ~/.ssh/known\_hosts

</td></tr><tr><td></td><td>sort -t. -k1,1n -k2,2n -k3,3n -k4,4n

</td></tr><tr><td>•

</td><td>echo 'Test' | tr '\[:lower:\]' '\[:upper:\]'

</td></tr><tr><td>•

</td><td>tr -dc '\[:print:\]' &lt; /dev/urandom

</td></tr><tr><td>•

</td><td>history | wc -l

</td></tr><tr><td colspan="2">**set operations** (Note you can [export LANG=C](http://www.pixelbeat.org/docs/env.html) for speed. Also these assume no duplicate lines within a file)

</td></tr><tr><td></td><td>sort file1 file2 | uniq

</td></tr><tr><td></td><td>sort file1 file2 | uniq -d

</td></tr><tr><td></td><td>sort file1 file1 file2 | uniq -u

</td></tr><tr><td></td><td>sort file1 file2 | uniq -u

</td></tr><tr><td></td><td>join -t'\\0' -a1 -a2 file1 file2

</td></tr><tr><td></td><td>join -t'\\0' file1 file2

</td></tr><tr><td></td><td>join -t'\\0' -v2 file1 file2

</td></tr><tr><td></td><td>join -t'\\0' -v1 -v2 file1 file2

</td></tr><tr><td colspan="2">**math**

</td></tr><tr><td>•

</td><td>echo '(1 + sqrt(5))/2' | bc -l

</td></tr><tr><td>•

</td><td>echo 'pad=20; min=64; (100\*10^6)/((pad+min)\*8)' | bc

</td></tr><tr><td>•

</td><td>echo 'pad=20; min=64; print (100E6)/((pad+min)\*8)' | python

</td></tr><tr><td>•

</td><td>echo 'pad=20; plot \[64:1518\] (100\*10\*\*6)/((pad+x)\*8)' | gnuplot -persist

</td></tr><tr><td>•

</td><td>echo 'obase=16; ibase=10; 64206' | bc

</td></tr><tr><td>•

</td><td>echo $((0x2dec))

</td></tr><tr><td>•

</td><td>units -t '100m/[9.58s](http://www.pixelbeat.org/misc/usain_bolt/)' 'miles/hour'

</td></tr><tr><td>•

</td><td>units -t '500GB' 'GiB'

</td></tr><tr><td>•

</td><td>units -t '1 googol'

</td></tr><tr><td>•

</td><td>seq 100 | (tr '\\n' +; echo 0) | bc

</td></tr><tr><td colspan="2">**calendar**

</td></tr><tr><td>•

</td><td>cal -3

</td></tr><tr><td>•

</td><td>cal 9 1752

</td></tr><tr><td>•

</td><td>date -d fri

</td></tr><tr><td>•

</td><td><nowiki>\[ $(date -d "tomorrow" +%d) = "01" \]</nowiki>

</td></tr><tr><td>•

</td><td>date --date='25 Dec' +%A

</td></tr><tr><td>•

</td><td>date --date='@2147483647'

</td></tr><tr><td>•

</td><td>TZ=':America/Los\_Angeles' date

</td></tr><tr><td></td><td>echo "mail -s 'get the train' P@draigBrady.com &lt; /dev/null" | at 17:45

</td></tr><tr><td>•

</td><td>echo "DISPLAY=$DISPLAY xmessage cooker" | at "NOW + 30 minutes"

</td></tr><tr><td colspan="2">**locales**

</td></tr><tr><td>•

</td><td>printf "%'d\\n" 1234

</td></tr><tr><td>•

</td><td>BLOCK\_SIZE=\\'1 ls -l

</td></tr><tr><td>•

</td><td>echo "I live in `locale territory`"

</td></tr><tr><td>•

</td><td>LANG=en\_IE.utf8 locale int\_prefix

</td></tr><tr><td>•

</td><td>locale | cut -d= -f1 | xargs locale -kc | less

</td></tr><tr><td colspan="2">**recode** (Obsoletes iconv, dos2unix, unix2dos)

</td></tr><tr><td>•

</td><td>recode -l | less

</td></tr><tr><td></td><td>recode windows-1252.. file\_to\_change.txt

</td></tr><tr><td></td><td>recode utf-8/CRLF.. file\_to\_change.txt

</td></tr><tr><td></td><td>recode iso-8859-15..utf8 file\_to\_change.txt

</td></tr><tr><td></td><td>recode ../b64 &lt; file.txt &gt; file.b64

</td></tr><tr><td></td><td>recode /qp.. &lt; file.txt &gt; file.qp

</td></tr><tr><td></td><td>recode ..HTML &lt; file.txt &gt; file.html

</td></tr><tr><td>•

</td><td>recode -lf windows-1252 | grep euro

</td></tr><tr><td>•

</td><td>echo -n 0x80 | recode latin-9/x1..dump

</td></tr><tr><td>•

</td><td>echo -n 0x20AC | recode ucs-2/x2..latin-9/x

</td></tr><tr><td>•

</td><td>echo -n 0x20AC | recode ucs-2/x2..utf-8/x

</td></tr><tr><td colspan="2">**CDs**

</td></tr><tr><td></td><td>gzip &lt; /dev/cdrom &gt; cdrom.iso.gz

</td></tr><tr><td></td><td>mkisofs -V LABEL -r dir | gzip &gt; cdrom.iso.gz

</td></tr><tr><td></td><td>mount -o loop cdrom.iso /mnt/dir

</td></tr><tr><td></td><td>cdrecord -v dev=/dev/cdrom blank=fast

</td></tr><tr><td></td><td>gzip -dc cdrom.iso.gz | cdrecord -v dev=/dev/cdrom -

</td></tr><tr><td></td><td>cdparanoia -B

</td></tr><tr><td></td><td>cdrecord -v dev=/dev/cdrom -audio \*.wav

</td></tr><tr><td></td><td>oggenc --tracknum='track' track.cdda.wav -o 'track.ogg'

</td></tr><tr><td colspan="2">**disk space** (See also [FSlint](http://www.pixelbeat.org/fslint/))

</td></tr><tr><td>•

</td><td>ls -lSr

</td></tr><tr><td>•

</td><td>du -s \* | sort -k1,1rn | head

</td></tr><tr><td>•

</td><td>df -h

</td></tr><tr><td>•

</td><td>df -i

</td></tr><tr><td>•

</td><td>fdisk -l

</td></tr><tr><td>•

</td><td>[rpm](http://www.pixelbeat.org/docs/packaging.html) -q -a --qf '%10{SIZE}\\t%{NAME}\\n' | sort -k1,1n

</td></tr><tr><td>•

</td><td>[dpkg](http://www.pixelbeat.org/docs/packaging.html)-query -W -f='${Installed-Size;10}\\t${Package}\\n' | sort -k1,1n

</td></tr><tr><td>•

</td><td>dd bs=1 seek=2TB if=/dev/null of=ext3.test

</td></tr><tr><td>•

</td><td>&gt; file

</td></tr><tr><td colspan="2">**monitoring/debugging**

</td></tr><tr><td>•

</td><td>tail -f /var/log/messages

</td></tr><tr><td>•

</td><td>strace -c ls &gt;/dev/null

</td></tr><tr><td>•

</td><td>strace -f -e open ls &gt;/dev/null

</td></tr><tr><td>•

</td><td>ltrace -f -e getenv ls &gt;/dev/null

</td></tr><tr><td>•

</td><td>lsof -p $$

</td></tr><tr><td>•

</td><td>lsof ~

</td></tr><tr><td>•

</td><td>tcpdump not port 22

</td></tr><tr><td>•

</td><td>ps -e -o pid,args --forest

</td></tr><tr><td>•

</td><td>ps -e -o pcpu,cpu,nice,state,cputime,args --sort pcpu | sed '/^ 0.0 /d'

</td></tr><tr><td>•

</td><td>ps -e -orss=,args= | sort -b -k1,1n | pr -TW$COLUMNS

</td></tr><tr><td>•

</td><td>ps -C firefox-bin -L -o pid,tid,pcpu,state

</td></tr><tr><td>•

</td><td>ps -p 1,2

</td></tr><tr><td>•

</td><td>last reboot

</td></tr><tr><td>•

</td><td>free -m

</td></tr><tr><td>•

</td><td>watch -n.1 'cat /proc/interrupts'

</td></tr><tr><td colspan="2">**system information** (see also [sysinfo](http://www.pixelbeat.org/scripts/sysinfo)) ('#' means root access is required)

</td></tr><tr><td>•

</td><td>uname -a

</td></tr><tr><td>•

</td><td>head -n1 /etc/issue

</td></tr><tr><td>•

</td><td>cat /proc/partitions

</td></tr><tr><td>•

</td><td>grep MemTotal /proc/meminfo

</td></tr><tr><td>•

</td><td>grep "model name" /proc/cpuinfo

</td></tr><tr><td>•

</td><td>lspci -tv

</td></tr><tr><td>•

</td><td>lsusb -tv

</td></tr><tr><td>•

</td><td>mount | column -t

</td></tr><tr><td>•

</td><td>grep -F capacity: /proc/acpi/battery/BAT0/info

</td></tr><tr><td>\#

</td><td>dmidecode -q | less

</td></tr><tr><td>\#

</td><td>smartctl -A /dev/sda | grep Power\_On\_Hours

</td></tr><tr><td>\#

</td><td>hdparm -i /dev/sda

</td></tr><tr><td>\#

</td><td>hdparm -tT /dev/sda

</td></tr><tr><td>\#

</td><td>badblocks -s /dev/sda

</td></tr><tr><td colspan="2">**interactive** (see also [linux keyboard shortcuts)](http://www.pixelbeat.org/lkdb/)

</td></tr><tr><td>•

</td><td>[readline](http://www.pixelbeat.org/lkdb/readline.html)

</td></tr><tr><td>•

</td><td>[screen](http://www.pixelbeat.org/lkdb/screen.html)

</td></tr><tr><td>•

</td><td>[mc](http://www.pixelbeat.org/lkdb/mc.html)

</td></tr><tr><td>•

</td><td>[gnuplot](http://www.pixelbeat.org/docs/web/access_log/analyzing.html)

</td></tr><tr><td>•

</td><td>links

</td></tr><tr><td>•

</td><td>xdg-open **.**

</td></tr><tr><td colspan="2">**miscellaneous**

</td></tr><tr><td>•

</td><td>[alias](http://www.pixelbeat.org/settings/.bashrc)hd='od -Ax -tx1z -v'

</td></tr><tr><td>•

</td><td>[alias](http://www.pixelbeat.org/settings/.bashrc)realpath='readlink -f'

</td></tr><tr><td>•

</td><td>set | grep $USER

</td></tr><tr><td></td><td>touch -c -t 0304050607 file

</td></tr><tr><td>•

</td><td>python -m SimpleHTTPServer

</td></tr></tbody></table>

&lt;!--font-size--&gt;google\_ad\_section\_start(weight=ignore)

# Linux commandline tips 3

- Download a file and uncompress it while it downloads

`$wget `[`http://URL/FILE.tar.gz`](http://URL/FILE.tar.gz)` -O - | tar xfz -`

- If you play loto, try this command to generate the 6 numbers :

`$echo $(shuf -n 6 -i 1-49 | sort -n)`

- To get the CPU temperature continuously on the desktop

`$while :; do acpi -t | osd_cat -p bottom ; sleep 1; done &`

- Search for large files and show size and location.

`$find . -size +100000k -exec du -h {} \;`

- Get a random Command

`$ls /usr/bin | shuf -n 1`

This is useful if you want to explore various random commands.

More commands :

- Bash logger :Log everything from a bash script to a file

`$script /tmp/log.txt`

- Using NMAP to check if a port is open or close

`$nmap -oG - -T4 -p22 -v 192.168.0.254 | grep ssh`

- Get the IP of the host your coming from when logged in remotely

`$echo ${SSH_CLIENT%% *}`