Table of Contents
- Basics
- Bell
- Cscope Code Indexing
- Date Manipulation
- Disk Operations
- Environment
- Exit Status of a Program
- Find
- Grep (searching)
- Kill a process
- Libraries
- Logging
- Using Man Pages
- Processor Affinity
- Python
- User and Group
Notes:
- A line that start with a "$" denotes a command line entry in a user shell / terminal.
- '#' can denote two things: root shell or comment. If a line starts with '$', then '#' and what follows is a comment.
- Most examples will work equally well on an Ubuntu desktop or an embedded Linux system built with Yocto (assuming the right packages are installed).
- Most commands have many options. Refer to the man pages for more information.
Command Line Basics
Let's determine our login and information about the machine we're using:
$ whoami postgres $ grep postgres /etc/passwd postgres:x:123:130::/opt/pgsql/data:/bin/bash # uid: 123, gid: 130, home directory: /opt/pgsql/data, shell: /bin/bash $ uname -a Linux <hostname> 4.15.0-64-generic #73-Ubuntu SMP <date> x86_64 x86_64 x86_64 GNU/Linux $ hostname <hostname> # info about our distribution $ lsb_release -a ... Distributor ID: Ubuntu Description: Ubuntu 18.04.3 LTS Release: 18.04 Codename: bionic
Annoying Bell
Turn off the bell you hear while working on the command line
edit /etc/inputrc:
# do not bell on tab-completion set bell-style none
Cscope
Quickly build a searchable cscope database / index of your C project:
$ find -L . -name '*.[chS]' > cscope.files $ cscope -b -q -k $ cscope -d
Date
date uses the following format: [MMDDhhmm[[CC]YY][.ss]]
# # assume it's noon on April 22 2019: # date 042212002019 Mon Apr 22 12:00:00 EDT 2019 # # check how timezone is set: # ls -l /etc/localtime lrwxrwxrwx 1 root root 27 Apr 22 10:12 /etc/localtime -> /usr/share/zoneinfo/EST5EDT # # change it to central: # ln -f -s /usr/share/zoneinfo/CST6CDT /etc/localtime # date Mon Apr 22 11:01:45 CDT 2019
Additional notes on date and timezone:
- Use ntp daemon to automatically update date and time
- The TZ setting can also be modified in /etc/profile
Basic Disk Operations
Tasks for creating a new drive partition mounting, testing, and fixing it:
# # format partitions on an unmounted drive: # fdisk /dev/sda # # create a filesystem on the third SDA partition: # mke2fs /dev/sda3 # # mount a partition at /mnt/drive: # mkdir -p /mnt/drive # mount /dev/sda3 /mnt/drive # # test and fix disk errors on the partition (unmount first) # e2fsck /dev/sda3 # # or to automatically fix errors and be verbose: # e2fsck -vy /dev/sda3
Environment
Control environment variables from the command line:
$ export var1="privacy" # note there are no spaces $ echo $var1 # return the value of "var1" privacy $ set | grep var1 var1=privacy $ echo "I like my $var1" I like my privacy $ unset var1 # remove the environemnt variable $ echo $var1 $ set | grep var1 $
Exit Status of a Program
If you're familiar with 'C' programming on Linux, you probably realize that many programs will return a meaningful value upon exit. You can poll this value on the command line as shown with a simple example below.
$ cd / # cd to root of file system $ ls bin boot ... $ echo $? 0 $ ls -l does-not-exist ls: cannot access 'does-not-exist': No such file or directory $ echo $? 2 $ man ls ... Exit status: 0 if OK, 1 if minor problems (e.g., cannot access subdirectory), 2 if serious trouble (e.g., cannot access command-line argument). ...
Find
Non-trivial examples using a very powerful but non-intuitive tool:
$ # find *.py files and copy to a temp directory $ find . -name '*.py' | xargs -I{} cp {} ~/temp $ # delete *.js files that aren't minified: $ find . -path '*.js' ! -path '*.min.js' | xargs rm $ # find my js files but exclude those in node_modules and build find . -path '*.js' ! -path "./node_modules/*" ! -path "./build/*" $ # Find source files in a C project and include symbolic links $ find -L . -name '*.[chS]' $ # same as above but include cpp files $ find -L . -name '*.[chS]' -or -name '*.cpp' $ # Search book directory tree for a pdf title, but exclude files that start with a '.' $ find . -name '[^.]*.pdf' | grep -i <part of title> $ # Let's do the same as above but prune books in the oreilly directory $ find . -path "./oreilly*" -prune -o -name '[^.]*.pdf' $ # Sort all files within a directory structure by date & time; print newest first $ find . -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort -r
Grep
Some useful grep options for searching through files:
$ # search recursively for "elf" as a word and case insensitive $ grep -iwR elf . $ # do the same thing but exclude binary files $ grep -iwIR elf . $ # find "elf" when it's at the end of a line, note use of regex here $ grep -iwR 'elf$' . $ # use expanded / full regexp to search for .html or .htm in file $ grep -E "\.html?" <file>
useful grep command line options:
- -i: case insensitive
- -n: output line number
- -w: select only those lines containing matches that form whole words
- -I: exclude binary files
- -R: search into the directories below
Kill a process
Suppose our thunderbird app isn't responding, and we want to kill it:
$ ps -e | grep thunderbird 3120 pts/1 00:01:01 thunderbird $ sudo kill -9 3120 $ ps -e | grep thunderbird $ # but with an app that we launched, there's an easier way: $ pgrep thunderbird 3253 $ pkill thunderbird $ pgrep thunderbird
Libraries
Show the shared libraries used by the run-time linker:
$ ldconfig -p 1334 libs found in cache `/etc/ld.so.cache' libzvbi.so.0 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libzvbi.so.0 libzvbi-chains.so.0 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libzvbi-chains.so.0 ... # grep for a particular library $ ldconfig -p | grep libwebkit libwebkit2gtk-4.0.so.37 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libwebkit2gtk-4.0.so.37
Note that the "so" suffix stands for "shared object"
Print the shared object dependencies of an executable:
ldd /bin/ping linux-vdso.so.1 (0x00007ffc81891000) libcap.so.2 => /lib/x86_64-linux-gnu/libcap.so.2 (0x00007faaa4d47000) libidn.so.11 => /lib/x86_64-linux-gnu/libidn.so.11 (0x00007faaa4b14000) libnettle.so.6 => /usr/lib/x86_64-linux-gnu/libnettle.so.6 (0x00007faaa48de000) libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007faaa46c3000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007faaa42d2000) /lib64/ld-linux-x86-64.so.2 (0x00007faaa5180000)
Note that ld-linux-x86-64.so.2 is the aforementioned run-time linker
Logging
Note: syslog can usually be found at /var/log
# # write to the kernel log: # echo Hello World > /dev/kmsg # tail -n 1 /var/log/syslog Apr 22 12:24:39 kernel: <12>Hello World # # write to syslog and stderr with specific tag # logger -s -t 'tag' 'hello world again' <13>Apr 22 12:28:28 tag: hello world again # tail -n 1 /var/log/syslog Apr 22 12:28:28 tag: hello world again
man pages
Use the man pages effectively:
$ # search for socket man pages $ man -f socket socket (7) - Linux socket interface socket (2) - create an endpoint for communication Socket (3perl) - networking constants and support functions $ # list socket(7) $ man -S 7 socket $ # search for man pages with socket in the short description: $ man -k socket Socket (3perl) - networking constants and support functions accept (2) - accept a connection on a socket accept4 (2) - accept a connection on a socket ... $ # walk through each man page for "socket": $ man -a socket ... $ # Don't forget about whatis $ whatis socket socket (7) - Linux socket interface socket (2) - create an endpoint for communication
Processor Affinity
Run a command on a particular CPU core
$ # Use a bit mask to specify the CPU $ # example: cat the cpu stats using CPU 1 (the second core) $ taskset 2 cat /proc/cpuinfo
Python from command line
Execute Python commands without entering interpreter shell:
$ python3 -c "print(hex(0x400<<8))" 0x40000 $ python3 -c "import math; F=10**6; print(2*math.pi*F)" 6283185.307179586 $ python3 -c "import site; print(site.getsitepackages())" ['/usr/local/lib/python3.6/dist-packages', ...]
User and Group ID
This example is run from a freshly installed embedded system as root.
# # return our groups: # groups root # # get our real and effective user & group IDs # id uid=0(root) gid=0(root) groups=0(root)