(Linux) shell tips
Command-line (unix shell) tips. Some may be bash- or linux-specific.
- Grepping mans
- mosh + tmux + systemd
- Entering docker container without docker
- Environment variables of a running process
- Find matching line, and extract the matching part
- Using less to follow files
- Parsing comma-separated string into a bash array
- Extracting a single file from the RPM package
- When you’re too lazy to explain everything
Grepping mans ¶
Here’s a piece of man git-log | xxd
:
00000a0: 2020 5f08 675f 0869 5f08 7420 5f08 6c5f _.g_.i_.t _.l_
00000b0: 086f 5f08 6720 5b3c 6f70 7469 6f6e 733e .o_.g [<options>
00000c0: 5d20 5b3c 7265 7669 7369 6f6e 2072 616e ] [<revision ran
00000d0: 6765 3e5d 205b 5b2d 2d5d 203c 7061 7468 ge>] [[--] <path
00000e0: 3e2e 2e2e 5d0a 0a0a 4408 4445 0845 5308 >...]...D.DE.ES.
08
is a backspace char — which means terminal will display this,
but grep won’t find it: it needs a help for yet another command,
col
:
$ man git-log | col -b | grep 'git log' | head -n 1
git log [<options>] [<revision range>] [[--] <path>...]
mosh + tmux + systemd ¶
Systemd-logind kills user processes when the session is over.
To overcome this, I’ve created the following one-line script
in my ~/bin
.
exec urxvt -e mosh "${1:-gd-ws}" \
--server='systemd-run --scope --user mosh-server new' \
-- tmux att
Explaining this command would make a nice article ;)
[1]
Entering docker container without docker ¶
docker exec
executes command within the container cgroup;
if this cgroup has hard CPU and/or RAM limitations, this
may affect your production code. If you have root access
to the box, you can use nsenter
instead:
nsenter --target $PID --mount --uts --ipc --net --pid
$PID
here is the process ID of one of the processes running
in the container, as seen from the host.
Example:
$ sudo nsenter --target 10372 --mount --uts --ipc --net --pid cat /proc/self/cgroup | head -n3
11:cpu,cpuacct:/
10:pids:/user.slice/user-500.slice/session-1.scope
9:memory:/
$ docker exec 2b341597dbf7 cat /proc/self/cgroup | head -n3
11:cpu,cpuacct:/init.scope/system.slice/docker-2b341597dbf7d223f820c1be8edc7c78c394b0f447547f4679f4926e36d07060.scope
10:pids:/init.scope/system.slice/docker-2b341597dbf7d223f820c1be8edc7c78c394b0f447547f4679f4926e36d07060.scope
9:memory:/init.scope/system.slice/docker-2b341597dbf7d223f820c1be8edc7c78c394b0f447547f4679f4926e36d07060.scope
Environment variables of a running process ¶
You can get them from /proc/$PID/environ
. Variables are NULL-separated. For example:
# cat /proc/`pgrep dockerd`/environ | xargs -0L1
LANG=ru_RU.UTF-8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NOTIFY_SOCKET=/run/systemd/notify
OPTIONS=
DOCKER_STORAGE_OPTIONS=
Find matching line, and extract the matching part ¶
There is -o
switch in grep
for that exactly.
$ amixer get Master | egrep -o '[0-9]{1,3}?%'
100%
100%
Using less to follow files ¶
less
can serve as a convenient replacement for tail -f
,
especially when you’re watching somewhat untrusted log
that may hack your terminal emulator:
less -R +F <file>
Parsing comma-separated string into a bash array ¶
parse_array () { local IFS=','; read -a "$1" < <(echo "$2"); }
This takes two arguments – name and content, and sets global variable with the given name to an array parsed from comma-separated contents. For example:
keys="host,port,service name,comment"
parse_array the_array "$keys"
for x in "${the_array[@]}"; do
echo "$x"
done
This prints:
host
port
service name
comment
Extracting a single file from the RPM package ¶
Beware of the traces of nasty hacks in the example below:
rpm2cpio net-tools-1.60-114.el6.x86_64.rpm | cpio -iv --to-stdout ./sbin/ifconfig > /sbin/ifconfig-compat
When you’re too lazy to explain everything ¶
it’s classy to render smile in Fira Mono when you can do smth like 😉. ↩︎