*** run Firefox as a separate user (and evtl. in a separate chroot environment, here only / care for /dst/anylinux if you do) *** > chroot / ... not necessary, we do it here as a no-operation/nop-example, why?: »xchroot -u bel /« for those who did not have the creativity to use xchroot, www.elstel.org/xchroot/, a download was formerly available at http://elstel.id - today ask E_.S. > su ffx > echo $HOME /home/ffx > id -a uid=4097(ffx) gid=100(users) Gruppen=100(users) > export DISPLAY=:0.0 > xhost No protocol specified xhost: unable to open display ":0.0" > ... copy/create an /home/ffx/.Xauthority > firefox 2>~/ffx-err.log 1>~/ffx-out.log & ... start the Firefox browser in the background, redirect stdout and stderr or: simply give firefox 1>/dev/null 2>&1 & .... 2>&1 redirect stderr(2) to the same as (1)~stdout, the & is necessary in order not to indicate a file with name “1” in the current directory, meant is: file descriptor #1, under Linux /dev/fd/1 — but not under BSD or any other Unix variant!, Linux specific and the directory needs to be mounted (mount | grep /dev/). > jobs -pl ... -p … show pids, -l … list jobs and do not merely output the pids *** X11/Xorg window system GUI-support for a separate user: *** $ echo $XAUTHORITY /var/run/lightdm/elm/xauthority AS root: $ cp /var/run/lightdm/elm/xauthority /home/bel/.Xauthority $ chmod 600 /home/bel/.Xauthority; chown bel:bel /home/bel/.Xauthority; ... not as strict, AFAIK as far as I know the X-clients don´t recuse to read a world-readable file; try if ›cat /home/bel/.Xauthority >/dev/null‹ produces no error message, user/group(chown) - access_rights(chmod) combination must fit! > ls -l /home/bel/.Xauthority -rw------- 1 bel bel 397 Jul 12 21:44 /home/bel/.Xauthority AS user: $ export XAUTHORITY=/home/bel/.Xauthority ... not needed, ~/.Xauthority is the per-default file name for the $XAUTHORITY of user bel, use ›unset XAUTHORITY‹ to remove a faulty variable, note that variables can have empty strings, which may break things as well – forbidden: export XAUTHORITY=""; $ export DISPLAY=:0.0 .... first X-server (number 0 zero), monitor #0 for people who have more than one monitor device; you can move a program with the mouse between the first and second monitor (at xrandr use, or an established “bumble-bee“ if I remember the program name correct “Hummel”:de), the second number just gives a default for launch time of your newl started X-programs. DISPLAY=:0.0 or DISPLAY=:0.1, /etc/X11/xorg.conf but I don´t write about these things here and today. / or: export DISPLAY=:0 The two programs that should give a more or less interesting output but no error message are: »xhost« and »xauth«. Generally AFAIK xhost tries to connect to the X-server like any other program does, so testing it with xhost shall/should be sufficient. $ *** copying file attributes from the user to the group and the all-user group: *** > ls -l hugo -rw-r--r-- 1 ffx users 0 Nov 24 01:14 hugo > chmod a+u,g+u hugo > ls -l hugo -rw-rw-rw- 1 ffx users 0 Nov 24 01:14 hugo *** pulse audio support for a separate user: *** AS user: $ id -a AS root: mkdy() { mkdir "$1"; chmod $2 "$1"; chown $3 "$1"; ls -ld "${1%/*}; } mkdy /run/user/1002 600 bel:bel mkdy /run/user/1002/pulse 700 bel:bel access rights: 4~read, 2~write, 1~execute; folders need 'execute', otherwise you can-not change-dir/cd into them, i.e. not use them! chmod 555 mydir … is common, only see, use but do not allow to change, create or delete anything inside chmod 600 ~/.ssh/id_rsa … absolutely necessary, the secure-remote-shell/ssh (from the OpenBSD project, nowadays used by al OS-es/operating systems including Linux and Windwos) will simply *recuse* to use this file otherwise, the secret key for encryption *must not* be world-readable!! bel:bel ~ user:group, uid-s & gid-s are completely different numbers (read: /etc/passwd & /etc/group); could be bel.uid=1002, bel.gid=502 $ id -a uid=1002(bel) gid=1002(bel) Gruppen=1002(bel),7(lp),81(audio),82(video),100(users) $ touch /run/user/1002/pulse/native > ls -l /run/user/1002/pulse/native -rw-r--r-- 1 root root 0 Nov 24 00:10 /run/user/1002/pulse/native $ mount --bind /run/user/1000/pulse/native /run/user/1002/pulse/native $ chmod a+u,g+u /run/user/1000/pulse/native > ls -l /run/user/1002/pulse/native srw-rw-rw- 1 elm elm 0 Sep 26 08:27 /run/user/1002/pulse/native The leading »s« is not a permission flag as you set it with ›chmod‹, it means that the file is of type »socket«. A socket-“file“ is not a file per_se, where you store data, here it is a point to point connection between the pulse audio server and the pulse audio client, which can be your music player, web browser or so on. The socket command (man 3 socket) creates a TCP or UDP socket for data transfer via IP, the internet protocol. This socket here is special, it only exists on this very computer, and can only be read by the specified user or another user with the specified group if chmod permissions are given to access via the memorized group affiliation: chmod/ls_-l output/input format: uuugggaaa, user, group, all-user attributes, last three falgs(rwx) specify what all users can do with the file, the three falgs in the middle count for the group only. $ cp /run/user/1000/pulse/pid /run/user/1002/pulse/ $ chown bel:bel /run/user/1002/pulse/pid $ ls -l /run/user/1000/pulse/ $ ls -l /run/user/1002/pulse/ ... the user name/uid of the socket file will be the same as »mount --bind« just mirrors a file the way that it keeps the same user and access bits become root: su/su root ... changes to root user, enter “exit“ or press [Ctrl]-[D] to return to the bash-shell that was running by the previous user, where you ordered the instruction ‘id -a’. sudo for-everycommand ... prefix every command with sudo; you needed to enter the root-password only the first time, if not half an hour passed by between entering one and the other command, exact time unknown, may be three or four minutes. AS user: export PULSE_SERVER=/run/user/1002/pulse pactl info xine /home/Music/02-Dire_Straits-Down_to_the_Waterline-HHI.ogg & firefox & ... start firefox in the background jobs -pl or: $ exec 99<>/dev/null ... open file descriptor 99 for read ’<’ and write ‘>’ by device(-file) /dev/null $ firefox >&99 2>&99 & ... start firefox redirecting stdin and stderr(#2) to just opened file descriptor #99 $ exec 99>&- ... close file descriptor 99 $ echo has >&99 sh: 99: Bad file descriptor *** closing file descriptors like stdin/stdout for a running program with gdb *** show ... display user defined variables/values/thing-of-any, like: show values; p $i info ... display things of the program that is being run, here /bin/firefox $ gdb -p 12345 [/bin/firefox] or: gdb /bin/firefox attach 12345 (gdb) info thread Id Target Id Frame * 1 process 2004032 "tioc" main () at /tmp//tioc.c:6 102 Thread 0x7fe2a407d640 (LWP 2004804) "LS Thread" 0x00007fe2d9cfc86a in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0 .... LS Thread is the “Load Stuck Thread”, tests if a web page still did not load after attempting to load it for five minutes, this thread is not highly occupied and we will use it here. Nonetheless gdb is known to create an own child thread for more advanced system calls, and file descriptor operations per se usually do not have an effect on the specific thread, but on the whole process comprising all threads instead; file descriptors are shared among all threads and considered to be part of the process as a whole. (gdb) thread 1 [Switching to thread 1 (process 2004032)] #0 main () at /tmp//tioc.c:6 6 res = ioctl(2,TIOCGWINSZ,&winsz); (gdb) thread apply 1 call (int)abs(-3) Thread 1 (process 2004032 "tioc"): $7 = 3 > grep -R O_WRONLY /usr/include/* /usr/include/asm-generic/fcntl.h:#define O_WRONLY 00000001 /usr/include/bits/fcntl-linux.h:#define O_WRONLY 01 ... we will open /dev/null for writing only (O_WRONLY) gdb, the gnu debugger does not know constants like O_WRONLY at gcc/clang, we will simply pass the numeric argument »1« (gdb) thread apply 102 call (int)open("/dev/null",1) Thread 102 (Thread 0x7fe2a407d640 (LWP 2004804) "LS Thread"): [New Thread 0x7fe2b67bd640 (LWP 2005206)] $1 = 73 ... file /dev/null has been sucessfully opened (otherwise the return value would be -1), and the handle of the new file descriptor is #73 (gdb) thread apply 102 call (int)dup2(73,1) Thread 102 (Thread 0x7fe2a407d640 (LWP 2004804) "LS Thread"): $2 = 1 ... take file descriptor #73 and replace file descriptor #1 to be the exactly same as #73 return value is ›1‹, what we passed as second argument - stdin #1; in case of error would be -1. return value of dup2 is simply the same as for the dup call, the newly allocated file descriptor, here given as second argument. dup does not have a second argument, only one, the source file descriptor. (gdb) thread apply 102 call (int)dup2(73,2) Thread 102 (Thread 0x7fe2a407d640 (LWP 2004804) "LS Thread"): $3 = 2 (gdb) detach Detaching from program: /usr/bin/firefox, process 2004321 [Inferior 1 (process 2004321) detached] (gdb) quit > ls -l /proc/2004321/fd/[012] lrwx------ 1 bel bel 64 Nov 24 02:43 /proc/2004321/fd/0 -> /dev/pts/7 l-wx------ 1 bel bel 64 Nov 24 02:53 /proc/2004321/fd/1 -> /dev/null l-wx------ 1 bel bel 64 Nov 24 02:53 /proc/2004321/fd/2 -> /dev/null > ls -l /proc/2004321/fd/73 l-wx------ 1 bel bel 64 Nov 24 02:42 /proc/2004321/fd/73 -> /dev/null ... the file descriptor we had opened with open("/dev/null",1) (gdb) thread apply 1 call (int)close(99) Thread 1 (process 2004032 "tioc"): $8 = 0 ___ return value of 0 zero means at the time close was issued no system fault or machine crash was known, however inherently to what the close system call will start the operating system kernel to initiate, problems with disk access, file descriptors, exclusive locks of file descriptors and inherent wait-for or hang-by such locks would usually occure some-a-time later, that is when your program has already continued to execute and before-of-it had returned from the close(99) call. Strange why close(99) did not return EBADF, supposedly file desciptor #99 did not exist. ... normally: close(2); dup(73); ... the newly duplicated file descriptor would automatically be opened where the last one was closed, that is stderr/fd#2. If another thread by accident called dup() at the same time it would however come first!, called like this: dup is not thread save, dup2 is. iff “too many file descriptors open“, why not care about ulimit? or ipcs, /dev/shm $ sysctl fs.file-nr fs.file-nr = 1020 0 70000 1020 The number of allocated file handles. 0 The number of unused-but-allocated file handles. 70000 The system-wide maximum number of file handles. $ ulimit -H -n ... hard limit of file descriptors, see: man bash [G]? ulimit[N][N] 524288 $ ulimit -S -n ... soft limit of file descriptors 1024 $ export LANG=C $ ulimit -Sn 2 ... lower the soft limit to only two file descriptors, that will be too low, minimum three are required for any program: stdin, stdout, stderr. $ /tmp/tioc sh: start_pipeline: pgrp pipe: Too many open files /tmp/tioc: error while loading shared libraries: libc.so.6: cannot open shared object file: Error 24 $ ulimit -Sn 1024 ... as we have only lowered the soft limit -S, we can raise it again. Note that as non-root user lowering the hard limit would work, and also be done in deed; but increasing the hard limit again to 1024 is not allowed. Ulimit is a bash builtin that triggers a Linux system call inside the kernel, but changing to the root user by the »sudo« or »su« executable is impossible at this time since we only have two instead of a minimum of a ten or so file descriptors. Note that loading shared librarys from /usr/lib[64]/...*.so will also require additional file descriptors /proc/»pid«/maps $ /tmp/tioc <35,117> ioctl-TIOCGWINSZ: Success > sleep 50000 & echo ,,,,$! [6] 2009387 ,,,,2009387 > cat /proc/2009387/maps 7f9a0c3b7000-7f9a0c3ba000 rw-p 001c2000 00:1b 2416994 /usr/lib64/libc-2.32.so 7f9a0c3e8000-7f9a0c3e9000 r--p 00000000 00:1b 2416987 /usr/lib64/ld-2.32.so ... > ls -l /proc/2009387/fd insgesamt 0 lrwx------ 1 root root 64 Nov 24 03:55 0 -> /dev/pts/27 lrwx------ 1 root root 64 Nov 24 03:55 1 -> /dev/pts/27 lrwx------ 1 root root 64 Nov 24 03:55 2 -> /dev/pts/27 lrwx------ 1 root root 64 Nov 24 03:55 99 -> /dev/null ... our custom exec 99<>/dev/null descriptor, it was inherited though not used. ... > tty /dev/pts/27 ... also inherited, the terminal device where characters are displayed and keyboard input is received, here virtual emulated by the xfce4-terminal window application, lightest would be xterm. This is different from the program that is currently executed inside the emulated terminal environment, say bash the known command shell from ‘man bash’. In former times terminals were real devices, a monitor with connected keyboard and a serial cable was used to send new characters to be displayed while keyboard input was transmitted to the computer contrary-the-way on the serial line. See also: » man terminfo, tput cols ... « > export nv=$'\e[0m' hv=$'\e[1m' lv=$'\e[0;37m' ev=$'\e[1;31m' > echo "${ev}This is an error!$nv" >&2 > echo "${hv}high video, ${nv}norm video, ${lv}low video$nv", like on old monochrome displays; many terminal devices were, I don´t know howit was f.i. with the VT100 // /usr/share/terminfo/v/vt100 ... emulation file, specifying what that terminal device featured/ was capable to do. --------------------------------------- > xprop | grep -i PID ... just click on the window of the firefox instance you are interested in; -i ~ ignore case, should not be needed here. works similarely to xprop, by a click on the X-window: > xkill ... terminate an X-program without regret. > killall xine ... kill every running instance of the xine program, if the program was started multiple times > killall -9 xine ,,,, terminate xine programs fatally, open TCP/IP-sockets will linger open and block from restarting a program that was an internet server like apache or perhaps cupsd, the print server, which opens a TCP socket on port :631, use http://localhost:631; does not need to be seen outside of you local machine, usually a so called »firewall« will block access to internet sockets served by your own computer (or also the other direction round if configured like this, see: iptables, shorewall/Mageia, ufw/Ubuntu, etc. – Debian does not have a default firewall, as I would perceive you configured manually with iptables or via an /etc/...-directrory, /etc is where all the default confiugration and system start/stop scripts (today: systemd/systemctl) reside) > ps -O user,group -p 2948938 PID USER GROUP S TTY TIME COMMAND 2948938 elm elm T pts/10 04:34:57 firefox --ProfileManager --new-instance --new-window --browser /tmp/mutt-attach.html ... ps -O any-additional-fields ___ just adds additional output fields, while -o all-and-only-this-fields does/counts the opposite __ try also ps -O user,group -p 2948938 h ... the »h« as last_but_not_least of a string of single characters says the heading line for not to be printed __ pid is the process-id, so every program that runs makes up a »process« at the operating system level , possibly with many threads of execution (see: pthreads), The different threads being executed independently and in parallel have common properties and data in commmon, including the environment block, parameters passed to the program at invocation time and things like file descriptors: stdin - standard input, stdout - standard output, stderr - standard output channel for error messages if you wanna redirect the primary output to a file on disk or forward it to another program in a »pipe«, like: "seq 7 | nl | tac". > pstree -p 2948938 | head firefox(2948938)-+-Isolated Servic(3982673)-+-{Isolated Servic}(3982677) | |-{Isolated Servic}(3982678) | |-{Isolated Servic}(3982679) | |-{Isolated Servic}(3982681) | |-{Isolated Servic}(3982682) | |-{Isolated Servic}(3982683) | |-{Isolated Servic}(3982684) | |-{Isolated Servic}(3982685) | |-{Isolated Servic}(3982686) | |-{Isolated Servic}(3982732) > kill -STOP/-CONT 2948938 > echo top -p $(ps -o pid --ppid 2948938 h | tr '\n' ',' | tr -d ' ' | sed 's#,$##') // h ... no heading line, ppid = parent-pid > top -p 346289,348344,1139592,1139595,1139632,1188100,1194132,1194177,1196195,1196246,1198286,1200331,1362692,1362695,2959302,2959362,2959400,2959442,2959593,2959642,3075195,3075215,3075290,3075389,3077433,3079500,3093778,3093781,3981860,3981865,3981902,3981917,3981954,3981960,3982029,3982040,3982087,3982108,3982155,3982177,3982193,3982268,3982278,3982285,3982369,3982372,3982406,3982439,3982487,3982550,3982554,3982673,3982712,3982766,3982769,3982773,4005178 top: PID-Begrenzung (20) überschritten > echo sed "s#|$##" sed s#|0# ... ??? can´t explain what is going on here‼, seems to be a special function of bash or the like > echo sed "s#|\$##" sed s#|$## ... □ ✓ … __ shielding a character with the backslash “\“ or "\\" respectively (backslash shielded by itself) `s being always counted a good idea; _ seems to be exactly like this[!} > vwsubpids() { top -b -n 1 | grep -E "^[ \t]*($(ps -o pid --ppid $1 h | tr "\n" "|" | tr -d " " | sed "s#|\$##"))[ ]"; } > declare -f vwsubpids vwsubpids () { top -b -n 1 | grep -E "^[ \t]*($(ps -o pid --ppid $1 h | tr "\n" "|" | tr -d " " | sed "s#|\$##"))[ ]" } grep -E "..." , formerly egrep "..." allows an extended regular expression to be specified, so f.i. "(apid|anotherpid|athirdpid|oranyother)", instead of grep "\(apid\|anotherpid\|athirdpid\|oranyother\)" — avoid double, triple or quadruple – backslashing with watch, bash -c or things as the like, counts in/un-controllable‼, … use an echo __yourthing__ to see what quoting and unquoting does, the point in using bash -c "..." is that things like »tac myfile | grep what« can only be executed in a special command shell like bash, csh, ksh or like-a-wise, the watch command does not implement more than to invoke a single command, so »watch top -b -n 1« works, but »watch "top -b -n 1 | grep anything" can´t work, creating a pipeline of two processes, top and grep here is something the watch command won´t dø, only bash, ksh, csh, dash (more or less the same as bash, counted more performant) will do. The trick is that you can specify a one-line command with multiple commands separated by »;« with a »bash -c "first; second; third;". Unfortunately something like » export vwsubpids, and bash -c "vwsubpids 2948938" won´t do the trick, whole procedures don´t count as exportable variables, they would need to fit the env-format a process, any process can be feeded with; bash-procedures count only valiently within bash and seem/are refused to become exported, would need to use something like »source /tmp/myprocs.sh;«. > vwsubpids 2948938 1200331 elm 20 0 3489660 951076 86976 S 6,2 2,9 4:56.72 Isolated Web Co 346289 elm 20 0 2589020 154772 44336 S 0,0 0,5 0:14.49 Isolated Web Co 348344 elm 20 0 2426116 45988 35220 S 0,0 0,1 0:11.45 Isolated Web Co ... > todo='top -b -n 1 | grep -E "^[ \t]*($(ps -o pid --ppid 2948938 h | tr "\n" "|" | tr -d " " | sed "s#|\$##"))[ ]"' > echo $todo top -b -n 1 | grep -E "^[ \t]*($(ps -o pid --ppid 2948938 h | tr "\n" "|" | tr -d " " | sed "s#|\$##"))[ ]" > echo watch bash -c "${todo@Q}" watch bash -c 'top -b -n 1 | grep -E "^[ \t]*($(ps -o pid --ppid 2948938 h | tr "\n" "|" | tr -d " " | sed "s#|\$##"))[ ]"' > watch bash -c "${todo@Q}" ..... works !; clue is here: the command line interpreter from which you invoke the ›watch‹ program strips the '...' – quotes before watch could ever see them; double and triple backslashing like \" \\\" or so is not very well disgetive for whom needs to write and later on then read the code·work_!, the bash-interpreter, csh alas does not have a ${myvariable@Q}, can add quoting to a text-string so that an interpreter like bash, 2test › bash -c "echo Hello World\!" ‹ will then later on remove the auotmatically backslashed text. … by the way, you can do a thing like this: > a=33; hug='abc'$a'def'; echo "$hug"; abc33def > top -b -n 1 | { for i in $(seq 8); do read; echo "$REPLY"; done; grep -E "^[ \t]*($(ps -o pid --ppid 2948938 h | tr "\n" "|" | tr -d " " | sed "s#|\$##"))[ ]"; } top - 07:43:00 up 52 days, 16 min, 5 users, load average: 0,20, 0,54, 0,46 Tasks: 540 total, 1 running, 536 sleeping, 3 stopped, 0 zombie %CPU(s): 1,9 us, 2,6 sy, 0,0 ni, 95,5 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st MiB Spch: 31950,5 total, 5081,5 free, 14631,6 used, 12237,4 buff/cache MiB Swap: 45759,3 total, 31245,9 free, 14513,4 used. 8152,2 avail Spch PID USER PR NI VIRT RES SHR S %CPU %MEM ZEIT+ BEFEHL 42109 elm 20 0 19988 4376 3364 R 18,8 0,0 0:00.03 top 1198286 elm 20 0 3163456 702528 62488 S 6,2 2,1 4:09.51 Isolated Web Co > top -b -n 1 | { for i in $(seq 6); do read; done; read; echo "$REPLY"; egrep " (1|2) "; } PID USER PR NI VIRT RES SHR S %CPU %MEM ZEIT+ BEFEHL 1 root 20 0 176684 6648 4404 S 0,0 0,0 0:18.37 systemd 2 root 20 0 0 0 0 S 0,0 0,0 0:00.14 kthreadd 1025 rtkit 21 1 153724 760 692 S 0,0 0,0 0:03.44 rtkit-daemon > ps axu | head -n 3 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 176684 6648 ? Ss Sep26 0:18 /sbin/init root 2 0.0 0.0 0 0 ? S Sep26 0:00 [kthreadd] > LANG=C man ps | sed -n '/^PROCESS STATE CODES/,/^[^ ]/p' -n ... does not print the input lines by default sed -n '3,5~2p' ... prints every 2nd line between the third and fifth line PROCESS STATE CODES Here are the different values that the s, stat and state output specifiers (header "STAT" or "S") will display to describe the state of a process: ‣ D uninterruptible sleep (usually IO) ... IO ~ input/output, f.i. reading or writing a file, to screen on a serial cable. ‣ I Idle kernel thread ... nothing to do, currently out of job – everything that is necessary `s being done. ‣ R running or runnable (on run queue) ... at computation, your fan will make noise and your CPU is apt to fry eggs after a few minutes. *** S interruptible sleep (waiting for an event to complete) ... oh´, so-what?, kill -STOP causes „interruptible sleep“, process is waiting for a so called operating system signal (OS-signal), man 7 signal; in our/this case it is the SIGCONT – signal. T stopped by job control signal t stopped by debugger during the tracing W paging (not valid since the 2.6.xx kernel) X dead (should never be seen) Z defunct ("zombie") process, terminated but not reaped by its parent For BSD formats and when the stat keyword is used, additional characters may be displayed: < high-priority (not nice to other users) ... look at ›man nice‹ N low-priority (nice to other users) L has pages locked into memory (for real-time and custom IO) ... man mlock s is a session leader ... man setsid, man daemon l is multi-threaded (using CLONE_THREAD, like NPTL pthreads do) ... man pthreads, but that does not prestay learning it. + is in the foreground process group ... man setpgid things about pthreads can be read in: „Bradford Nichols, Dick Buttlar, Jacqueline Proulx Farrel: Pthreads Programming, A POSIX Standard for Better Multiprocessing – ISBN 1-56592-115-1, O`Reilly“ things about mlock, setpgid, daemon and setsid in: „Robert Love: Linux System Programming, O`Reilly – ISBN 978-1-449-33953-1“ OBSOLETE SORT KEYS ** about sed: /beginning/,/end/c ... execute command »c« between and including lines /beginning/ and /end/, both interpreted as regular expressions /^at-the-beginning-of-line/ /at-the-end-of-line$/ [^ ] ... non-space character, [^abc] ... any character that is not 'a', 'b' or 'c' /begin/,/end/{ ... } ... list of subcommands that is here executed for the lines between-including begin ... end /^[^ P][^ R]/ .... a line of text that starts with two letters, the first letter must not be 'P', the second must not be 'R', likely then something different than /^PROCESS/ q ... quit command, here: quit if such a line is encountered that the first two letters are non-space and neither 'P' or 'R' at position 1 and 2, respectively. p ... print what we have, here: only if the ›q‹-command has not quitted the subcommand list we are in, before. ** two ways not to output the last line: a.) ›$‹ ... significates the last line that was given as input when invoking sed, here: last line reached and if-so quit before printing »p«. b.) use > LANG=C man ps | sed -n '/^PROCESS STATE CODES/,/^[^ ]/p' | sed -n '$q;p' > LANG=C man ps | sed -n '/^PROCESS STATE CODES/,/^[^ ]/{/^[^ P][^ R]/q;p}'a ... info sed; man sed; ******* a bit more about Unix/Linux/BSD console tricks, that may be seen in a way related ******* ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── > LANG=C locale LANG=C LC_CTYPE="C" ... character type, well what the programs you start, f.i. »which lynx« will know or pay attention to. LC_NUMERIC="C" ... numeric format, 100.20€ — not 100,20€, not all programs make a difference, end-user applications like gnumeric or localc/oocalc generally will; programming languages like python don´t. LC_TIME="C" ... test the »date« command LC_COLLATE="C" ... how characters like ‘ä’ ‘ö’ ‘œ’ or perhaps a clear-lettered ‘oe‘ would behave in sort-order, look at the »sort« - command LC_ALL= > locale LANG=de_AT.UTF-8 LC_CTYPE="de_AT.UTF-8" LC_NUMERIC="de_AT.UTF-8" LC_TIME="de_AT.UTF-8" ... LC_ALL= > echo "$LANG" > env | grep ^LANG= de_AT.UTF-8 LANG=de_AT.UTF-8 ... here like the data is written directly in the process header of a Unix/Linux/BSD-process, you can read it out like this directly with C-functions like > mypid=$$; grep -z LANG /proc/$mypid/environ | tr '\000' '\n' LANG=de_AT.UTF-8 LANGUAGE=de_AT.UTF-8:de GDM_LANG=de_DE.utf8 > mypid=$$; grep -z LANG /proc/$mypid/environ | od -An -tc | tr -d '\n '; echo; LANG=de_AT.UTF-8\0LANGUAGE=de_AT.UTF-8:de\0GDM_LANG=de_DE.utf8\0 ___ the echo is here to conclude the text with a new-line ‘\n’, -An means address-printing:none, and -tc means type 1-byte-character & thus byte-wise > ... | od -An -w$COLUMNS -txCa 4c 41 4e 47 3d 64 65 5f 41 54 2e 55 54 46 2d 38 00 4c 41 4e 47 55 41 47 45 3d 64 65 5f 41 54 2e 55 54 46 2d 38 3a 64 65 00 47 44 4d 5f 4c 41 4e 47 3d 64 65 5f 44 45 2e 75 74 66 38 00 L A N G = d e _ A T . U T F - 8 nul L A N G U A G E = d e _ A T . U T F - 8 : d e nul G D M _ L A N G = d e _ D E . u t f 8 nul > tput cols/lines; tty; echo $COLUMNS $LINES $TTY; kill -WINCH $$ ... signal that would need to be caught for a C-program in order to take notice of resizing a terminal, columns and lines can be queried with an ioctl - system call: cat >/tmp/tioc.c < #include #include int main() { int res; struct winsize winsz; res = ioctl(2,TIOCGWINSZ,&winsz); if (res>=0) printf("<%i,%i>\n", winsz.ws_row, winsz.ws_col ); perror("ioctl-TIOCGWINSZ"); return res==-1 ? errno : res; } EOQ > for i in /usr/share/man/*/*.xz; do xzgrep -l "winsize" $i; done /usr/share/man/man1/bash.1.xz /usr/share/man/man1/builtins.1.xz /usr/share/man/man1/perlfaq8.1.xz /usr/share/man/man2/ioctl_tty.2.xz /usr/share/man/man3/openpty.3.xz /usr/share/man/man3/Term::ReadLine::Gnu.3pm.xz /usr/share/man/man5/sudo_logsrv.proto.5.xz /usr/share/man/man8/sudo_plugin.8.xz > man 2 ioctl_tty > man bash /^[ ]*Parameter Exp ... will search for "Parameter Expansion" at the beginning of the line, iff the man-page is being viewed. [n] / [N] ... goes to the next or previous match of the regular expression [q] quit viewing the man page > man bash [G] ... goes to the end of the man page ? declare ... searches for declare with three spaces in front, in backward order. [n] next occurrence of the pattern in search order, that is backwards here, — the [g] ... go back to the beginning of the page > man bash 72.8% ... will also go to where the »declare« – builtin is found [h] ... view a help screen, including how to set reading-/bookmarks > man man ... general things on where-from to read into the docs that are supplied, also: the 7 man sections explained, man -k, apropos, ...  ★ Web browsers like KDE/Konqueror ★ can also view man pages, enter “#strstr” or “man:/strpbrk” in the address bar, instead of "http://ix2w.org". At the currently supplied version of konqueror there is a bug, you need to select »View → Viewing Mode → KHTML«. use: > konqueror --part khtml "#strstr" & or go to: »Settings → Customize Konqueror (last menu entry)« > ls -ld ~/.* -rw-rw---- 1 bel users 10654 Okt 11 08:12 /home/bel//.config ... > echo ~ /home/bel/ > echo .[lcw]* .cache .config .lesshst .local .w3m .wget-hsts ___ that is the file pattern extension of the shell_console_program, called »shell pattern extension« or »globbing« goes do be done automatically by the shell (bash, ksh, etc.) before a command like here ›echo‹ is executed. It is not done if you quote the text!, array assignments work: set -- *.jpeg; echo $*; or: pics=(*.jpeg *.gif); echo ${pics[@]}; arrays are a special feature of the bash-shell, but you can use the parameters "$1 $2 $3 ..." as such an (set -- $1 $2), use »shift« to assign ›$‹1="$2", ›$‹2="$3", etc. > cat >>~/.config/konquerorrc ... don´t forget the double-redirection, otherwise the file is overwritten and destroyed!!, may copy if to "cp konquerorrc konquerrc.sav", first. [UserSettings] HomeURL=https://www.kde.org/ StartURL=konq:konqueror [Ctrl]-[D] .... outputs a '\004', 4th character in the ascii character set after nul or '´\000' respectively needs to be the first character in a line, so press [↲] return before (what would be '\012', 10th character or [Ctrl][J]). > sed -i 's#^HomeURL=.*$#HomeURL=http://index2web.org#' ~/.config/konquerorrc ... »-i« stands for in-place, edit an existing file instead of processing the file and printing the result to stdout ___ »^« ... beginning of the line, ___ »$« ... end of the line > read -n 1 mychar [Ctrl][D] > echo "$mychar" | od -An -tca 004 \n eot nl ... the character in ${mychar} counts as end-of-text character (eot), the [Ctrl][J] as a new-line (nl), all characters up to the space '\040' count as control characters, the character with number zero '\000' is used as »string delimiter« in C, C++ and many related programming languages, the environment block in the process control header (/proc/»pid«/environ) is also in same format, the block being delimited by a double '\z\z', that is the same as an empty string as last - not containing a "»var«=" prefix. > echo -n 'aa' | tr a '\000' | od -An -tca \0 \0 ... the »echo “-n“« is necessary in order not to conclude add an ›nl‹ to the string output, if you program in C and use printf you will need not to forget about the nl: "Hello World!\n" nul nul ... so take care of \000 being special, most programs don´t allow it(!), »grep -z« and »tr« are an exception. for i in /usr/share/man/*/*.xz; do xzgrep -le "\" $i; done /usr/share/man/man0p/stropts.h.0p.xz /usr/share/man/man1/apropos.1.xz ... > man 0p stropts.h | grep --color -C 2 -e "\" ... 3 is the general Library/C – command man page section, 3p is the same for Posix-Standard, Posix Standard is a minimum standard interface for different sorts of Unix, including Linux, BSD and comercial Unixes. The first known and available Unix-implementation was „System V“, very old standards conform to ›System V‹. The header shall define the strioctl structure, which shall include at least the following members: int ic_cmd ioctl() command. char *ic_dp Pointer to buffer. int ic_len Length of data. -- char l_name[FMNAMESZ+1] A STREAMS module name. gcc -o /tmp/tioc /tmp//tioc.c /tmp/tioc /tmp/tioc 0/dev/null 2>/dev/nul ... redirect stdin~0, stdout~1, stderr~2 to the byte-shredder and no-input device, also: /dev/stdin, /dev/fd/0, etc. or: > urpmq -y glibc ... that was for Mageia, Debian/Ubuntu is: ›apt-cache search‹, ›apt-get install‹, ›apt-file‹ or simply: ›aptitude‹ & ›tsel‹/›tasksel‹ don´t know the exact name of the command. > urpmi glibc-static-devel ... install and query for software packages in-at Mageia, -y gives a fuzzy instead of an exact & entire match, -Y same case-insensitive > urpmq -f glibc-static-devel | tr '|' '\n' | head -n 3 glibc-static-devel-2.32-14.mga8.x86_64 glibc-static-devel-2.32-15.mga8.x86_64 glibc-static-devel-2.32-16.mga8.x86_64 > urpmq -l glibc-utils | grep /bin/ | sort -u > xtrace --help , ... also: strace, ltrace, gdb, gdb-server > ldd /tmp/tioc not a dynamic executable > objdump -f /tmp/tioc /tmp/tioc: file format elf64-x86-64 architecture: i386:x86-64, flags 0x00000112: EXEC_P, HAS_SYMS, D_PAGED start address 0x0000000000401bc0 > file /tmp/tioc /tmp/tioc: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=5d4968b70a56133a695d93402fad665a08f06da3, for GNU/Linux 3.2.0, with debug_info, not stripped > gcc --static -Wl,--strip-all -o /tmp/tioc /tmp//tioc.c > file /tmp/tioc /tmp/tioc: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=1e4f15be7f41cacfb92d75d26f201be3e0e8064a, for GNU/Linux 3.2.0, stripped > uname -a Linux localhost 5.15.126-desktop-1.mga8 #1 SMP Fri Aug 11 21:17:00 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux ... SMP ~ symmetric multiprocessing, mga8 is Mageia Distribution - Version 8, also: > cat /etc/release /etc/redhat-release /etc/system-release /etc/os-release Mageia release 8 (Official) for x86_64 Mageia release 8 (Official) for x86_64 Mageia release 8 (Official) for x86_64 NAME="Mageia" (...) ID_LIKE="mandriva fedora" SUPPORT_URL="https://www.mageia.org/support/" BUG_REPORT_URL="https://bugs.mageia.org/" see also: > iconv -c -f utf8 -t iso88591 myfile.txt utf8 ... multibyte coding of utf, all characters of the world shall be part of iso88591 ... ANSI-standard for an 8-bit or one-byte — one-character code -c ... omit unknown characters, -f ... from, -t to, -l write all from- and to-codes that are supported, bspw cp850 and iso8859-15 (includes »€« - sign).