:date: 2012-06-05 10:03 .. index:: linux, tech Linux tools =========== Just some reminders for Linux-Tools and commands... -------- mkfifo - Named Pipes -------------------- Instead of redirecting the output of a command to a new one, you can use named pipes instead .. code:: bash $ mkfifo newpipe $ tail > newpipe Behind that simple command lies a whole chapter of named pipes, usage scenarios and things to do wrong. What you can basically can do is communicate between different processes using a pip-file (FIFO). `More Info `__. -------- col - Filter reverse line feeds from input ------------------------------------------ Useless? Well, handy to save man pages as plain-text ... .. code:: bash $ man less | col -b > less.txt -------- lsblk ----- :command:`fdisk` is out, :command:`lsblk` is in (when it comes to display the current block devices and their settings): .. code:: bash NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 111,8G 0 disk ├─sda1 8:1 0 243M 0 part /boot ├─sda2 8:2 0 1K 0 part └─sda5 8:5 0 111,6G 0 part └─sda5_crypt (dm-0) 252:0 0 111,6G 0 crypt ├─mint-root (dm-1) 252:1 0 103,8G 0 lvm / └─mint-swap_1 (dm-2) 252:2 0 7,7G 0 lvm [SWAP] sdb 8:16 0 1,4T 0 disk └─sdb1 8:17 0 1,4T 0 part /media/jt/8a9d3a12-7e3a-431f-871f-5e0e21ca09c8 sr0 11:0 1 1024M 0 rom loop0 7:0 0 120M 0 loop └─truecrypt1 (dm-3) 252:3 0 119,8M 0 dm /media/truecrypt.system -------- make ---- :program:`Make` is more handy than actually considered by the most admins. You can use it to automatically maintain a couple of files and keep them updated by just running one command. The clue lies within the :file:`makefile`-file which you create where you define all the dependencies and commands to run. For example a makefile can look like this: .. code:: bash sampleexec : src1.o src2.o gcc -o sampleexec src1.o src2.o src1.o : src1.c gcc -c src1.c src2.o : src2.c gcc -c src2.c This results in the following procedure done by make for creating the file :file:`sampleexec`: #. Sees that :file:`sampleexec` depends on the object files :file:`src1.o` and :file:`src2.o`. #. Looks for the target definition of the two object files. #. Sees that :file:`src1.o` depends on the file :file:`src1.c`. #. Executes the commands given in :file:`src1.o`'s rule and compiles :file:`src1.c` to get the object file. #. Similarly looks at the target :file:`src2.o` and compiles the object files. #. Prepares :file:`sampleexec` by combining the two object files. -------- Exit status ----------- How to get the exit status from a piped Command-shell (where the exit status usually comes from the last command) In Bash the exit codes are provided in the special array :samp:`PIPESTATUS`. :samp:`cmd1`-exit code is in :samp:`${PIPESTATUS[0]}`, :samp:`cmd2`-exit code in :samp:`${PIPESTATUS[2]}`, so that :samp:`$?` is always the same as :samp:`${PIPESTATUS: -1}`. .. code:: bash cmd1 | tail -n 2 if [ ${PIPESTATUS[0]} -ne 0] then echo “cmd1 failed.” EXIT_CODE = 1 fi -------- Tail - Multitail ---------------- For controlling more than a single file with :command:`tail -f` you simply need to specify the additional files .. code:: bash $> tail -f /varlog/messages -f /var/log/syslog You’ll get an output like this: .. code:: bash ==> messages <== Nov 22 00:43:07 laptop kernel: [ 61.487969] ADDRCONF(NETDEV_UP): eth0: link is not ready ==> syslog <== Nov 22 00:43:31 laptop pulseaudio[1773]: ratelimit.c: 1 events suppressed ==> messages <== Nov 22 00:43:31 laptop pulseaudio[1773]: ratelimit.c: 1 events suppressed ==> syslog <== Nov 22 00:45:44 laptop ntpd[1118]: kernel time sync status change 6001 So that keeps you updated. If you want it in a different way you could go for `multitail `__. That lists like the original :command:`tail`, but opens a couple of windows to switch between. -------- mmv --- Renaming files can be a pain in the ass. Especially when renaming a couple of files which only have slight error in the naming (according to your idea of proper naming). The tool :program:`mmv` (available from the repositories) can fix this. Assuming you've got a file called :file:`artists_-_title-stupid comment.mp3` and you want to rename it to a simple :file:`artist-title.mp3` and do this for all files in a directory: .. code:: bash $ mmv \*_-_\*-\*.mp3 \#1-\#2.mp3 And done. Keep also an eye on the parameter switches available, that e.g. let make you a copy instead of overwriting the original file. -------- Mass File Renaming ------------------ :program:`Find` is your buddy here: .. code:: bash # Remove stupid special characters $ find . -maxdepth 1 -type f | rename 's/ /_/g' $ find . -maxdepth 1 -type f | rename 's/\(//g' $ find . -maxdepth 1 -type f | rename 's/\)//g' $ find . -maxdepth 1 -type f | rename 's/\,//g' $ find . -maxdepth 1 -type f | rename "s/\'//g" $ find /tmp/ -depth -name "* *" -execdir rename 's/ /_/g' "{}" \; Alternatively have a look at :program:`detox`. -------- Screen ------ Yeah, yeah.. common virtual terminal tool. Moving Terminals to new position """""""""""""""""""""""""""""""" * change to the window you want to mo* * type (for example) :samp:`^x:number 1` * :samp:`^x` is the host key (usually :samp:`^a` on most machines) * :samp:`:number` (typed literally) is the command * :samp:`1` (as a digit) the number to move the current screen to Resizing splittet windows """"""""""""""""""""""""" * type (for example) :samp:`^x:resize -4` * :samp:`^x` is the host key (usually :samp:`^a` on most machines) * :samp:`:resize` is the command * :samp:`-4` (as a digit) the number of lines to make the current window smaller. Logging """"""" You can either make a hard copy or switch on the logging of the terminal window you're in Hardcopy '''''''' * Command: :command:`hardcopy` | :command:`(C-a h, C-a C-h)` | Writes out the current display contents to the file :file:`hardcopy.n` in the window's default directory, where n is the number of the current window. This either appends or overwrites the file if it exists, as determined by the :command:`hardcopy_append` command. * Command: `hardcopy_append state` | (none) | If set to :samp:`on`, screen will append to the :file:`hardcopy.nr` files created by the command :command:`hardcopy` otherwise, these files are overwritten each time. * Command: :command:`hardcopydir directory` | (none) | Defines a directory where hard copy files will be placed. If unset Hardcopys are dumped in screen's current working directory. Continuous logging '''''''''''''''''' * Command: :command:`log [state]` | :command:`(C-a H)` | Begins/ends logging of the current window to the file :file:`screenlog.n` in the window's default directory, where n is the number of the current window. If no parameter is given, the logging state is toggled. The session log is appended to the previous contents of the file if it already exists. The current contents and the contents of the scroll back history are not included in the session log. Default is :samp:`off`. * Command: :command:`logfile ` | (none) | Defines the filename of the logfile. I prefer to use something like :file:`screenlog.%Y%m%d.console_%n`. The command also can use the bash environmental variables like e.g. :samp:`$HOME`. But what I can't do is redirect the output into an encfs encrypted folder. * Command: :command:`logstamp after ` | (none) | Drops a timestamp into the logs after the number of seconds specified. -------- VI -- `VI `__ just crashed (well, it was `VIM `__ . Bastard. Recovery """""""" But I learned something new about recovery: Within :program:`vi` .. code:: bash :rec: gets you what you lost. In my case when using :program:`mutt` I found the file in :file:`/tmp`. The `VIM Documentation `__ has as well a chapter about recovery you might want to check. Swapping Character """""""""""""""""" If you're like me and you're typing sometimes to fast, this will swap the current character with the next one: .. code:: bash xp Upper/Lowercase """"""""""""""" Inside :program:`vi` you can easily convert whole lines or the whole file to uppercase or lowercase letters: .. code:: bash :%s/.*/\L&/g # All letters to lowercase :%s/.*/\U&/g # All letters to uppercase -------- Apt --- .. code:: bash # Install application dependencies $ apt-get build-dep -------- Dirstack, pushd, popd --------------------- If you temporarily need to build up a stack of some directories you're gonna switch between you can use the :program:`dirs` stack and the tools :program:`pushd` and :program:`popd` to access them. * :command:`dirs`: Shows the current stack. * :command:`pushd`: Adds directories to the stack or/and switches between them. | :command:`pushd +2`: jump to the second entry and switch to the directory | :command:`pushd .`: Add the current directory to the stack | :command:`pushd`: Switcht the first two entries of the stack and change to the new top directory. * command:`popd`: Removes the first entry of the stack and changes the folder to it. -------- CDPATH ------ The search path for the :command:`cd` command. This is a colon-separated list of directories in which the shell looks for destination directories specified by the cd command. A sample value is :samp:`.:~:/usr`. By placing common directories in this variable we can change common directories without navigating there. .. code:: bash (pwd = /home/juser) cd /usr/local/projects/abc vs. cd abc (pwd = /usr/local/projects/abc) (pwd = /usr/local/projects/abc/src/db/old/migration/) cd ../../../.. vs. cd abc (pwd = /usr/local/projects/abc) Indeed, one can find many subtle uses for this feature. A reasonable list to start with on a Red Hat Linux system, for example, might be .. code:: bash .:~:~/docs:/mnt:/usr/src/redhat:/usr/src/redhat/RPMS:/usr/src:/usr/lib:/usr/local .. NOTE:: An empty entry (:samp:`::` or a leading or trailing :samp:`:`) in :samp:`$CDPATH` (or in :samp:`$PATH`) is interpreted as the current working directory! Configure options for a build package ------------------------------------- Sometimes you have to recompile an already installed package just to add a single option that is missing in the standard packages that comes from your sources. You might wonder what where the default options it was compiled with. * The easiest thing to do may be to look at the build logs for the package in question. You can find them by starting at, e.g., https://launchpad.net/ubuntu/+source/asterisk](https://launchpad.net/ubuntu/+source/asterisk, then follow the link for the version you care about (in this case: https://launchpad.net/ubuntu/maverick/+source/asterisk/1:1.6.2.7-1ubuntu1.1). * Under the :samp:`Builds` header, you'll see a link for each architecture the package was built on. Don't worry about this too much, and just pick one - I'll look at amd64. * On the build record page, there's a link to the buildlog - https://launchpadlibrarian.net/62593317/buildlog_ubuntu-maverick-amd64.asterisk_1%3A1.6.2.7-1ubuntu1.1_BUILDING.txt.gz * And if you search the log for :samp:`./configure`, you'll find this: .. code:: bash PATH=$PATH:/build/buildd/asterisk-1.6.2.7/debian/dummyprogs ./configure \ --host=x86_64-linux-gnu --build=x86_64-linux-gnu \ --prefix=/usr \ --mandir=\${prefix}/share/man \ --infodir=\${prefix}/share/info \ --with-cap \ --with-gsm \ --with-imap=system \ --with-pwlib=/usr/share/pwlib/include/ \ --with-h323=/usr/share/openh323/ -------- Timezone adjustements --------------------- Occasionally timezones are a bit off and that has quite a negative impact on your logs and other data, where time is a kind of - well: critical information. So basically everywhere. So when you find yourself in a different timezone than you think it should be... .. code:: bash shell> cat /etc/timezone Etc/UTV adjust it by tuning... .. code:: bash $ sudo dpkg-reconfigure tzdata Don't forget to restart the :program:`cron`-daemon. He doesn't get the new timezone until being restarted. .. code:: bash $ sudo systemctl restart cron -------- Copying files ------------- Some nice and neat tricks to get files from one machine to another. Netcat """""" On the receiver side: .. code:: bash nc -l 12345 > file.tar On the sender side (three possibilities): .. code:: bash $ nc x.x.x.x 12345 < file.tar $ cat file.tar > /dev/tcp/x.x.x.x/12345 (without netcat) $ pv file.tar | nc x.x.x.x 12345 (with status) Python """""" .. code:: bash python2# python -m SimpleHTTPServer python3# python -m http.server It spawns a proper HTTP server (including directory listing) sharing the current folder.