Tag Info

Hot answers tagged

24

Rather than having to pick a file descriptor and hope it's available: exec 4< /dev/watchdog # Was 4 in use? Who knows? this notation asks the shell to pick a file descriptor that isn't currently in use, open the file for reading on that descriptor, and assign the number to the given variable (fd). $ exec {fd}< /dev/watchdog $ echo $fd 10


17

First, note that $@ without quotes makes no sense and should not be used. $@ should only be used quoted ("$@") and in list contexts. for i in "$@" qualifies as a list context, but here, to loop over the positional parameters, the canonical, most portable and simpler form is: for i do something with "$i" done Now, to loop over the elements starting from ...


17

Reading the bash man page gives the following information: for (( expr1 ; expr2 ; expr3 )) ; do list ; done First, the arithmetic expression expr1 is evaluated according to the rules described below under ARITHMETIC EVALUATION. [...] and then we get this section ARITHMETIC EVALUATION The shell allows arithmetic expressions to be ...


13

Avoid loops in shells. If you want to do arithmetic, use awk or bc: awk ' BEGIN{ for (i = 4.00; i < 5.42; i+ = 0.02) print i }' Or bc << EOF for (i = 4.00; i < 5.42; i += 0.02) i EOF Note that awk (contrary to bc) works with your processors double floating point number representation (likely IEEE 754 type). As a result, ...


9

[A-Z] in bash matches all characters that sort after A and sort before Z. In your locale, c probably sorts in-between B and C. $ printf '%s\n' A a á b B c C Ç z Z Ẑ | sort a A á b B c C Ç z Z Ẑ So c or z would be matched by [A-Z], but not Ẑ or a. $ printf '%s\n' A a á b B c C Ç z Z Ẑ | pipe> bash -c 'while IFS= read -r x; do case $x in [A-Z]) echo ...


8

Your Ctrl-r is being intercepted by the kernel-based terminal cookied line processing engine. While sleep is running, the terminal is in cooked mode, which means that the kernel-based tty line editor is working. The tty line editor supports rudimentary command line editing. The erase key (usually set to Ctrl-h (backspace) or Del) and the kill key (usually ...


8

Note that when using range expressions like [a-z], letters of the other case may be included, depending on the setting of LC_COLLATE. LC_COLLATE is a variable which determines the collation order used when sorting the results of pathname expansion, and determines the behavior of range expressions, equivalence classes, and collating sequences within ...


7

I think you want the shift builtin. It renames $2 to $1, $3 to $2, etc. Like this: shift for i in "$@"; do echo $i done


7

I suggest to hire grep for this job: $ OPTS="\"-name user -age 20 -where Asia -eats Brains\"" $ grep -Po -- '-where \K\w*' <<< "$OPTS" Asia Explanation: -P: perl compatible regular expression -o: show only matching parts \K: drop everything before that point \w*: match word constituent (synonym for [_[:alnum:]]) To add " to the list of ...


7

POSIXly: after_first_where=${opts#*-where } word_after_where=${after_first_where%% *} Or to allow any number of blanks between words: after_first_where=${opts#*-where} word_after_where=${after_first_where#"${after_first_where%%[![:blank:]]*}"} word_after_where=${word_after_where%%[[:blank:]]*} Or you could do: unset IFS; set -f # split on blanks, no ...


6

The form: {var}<filename made the shell open file filename for reading and store file descriptor number in variable var. There's no space allowed between {var} and redirection operators, and the file descriptor number will be greater than or equal 10. This feature was original from ksh (from version ksh93r in 2006), bash copied it a lot later in ...


6

It's not that much that there's not output as it's coming in chunks. Like many programs, when its output is no longer a terminal, cut buffers its output. That is, it only writes data when it has accumulated a buffer-full of it. Typically, something like 4 or 8 kiB though YMMV. You can easily verify it by comparing: (echo foo; sleep 1; echo bar) | cut -c2- ...


5

The structure of a pipeline doesn't allow time in the middle, only at the start of the pipeline. Also, time is a "shell keyword", as shown by type time. But nothing forbids the use of compound commands (and time each): time comm1 | ( time comm2 ) So, you could workaround using a sub-shell, like this: echo "12" | ( time python3 -c "a=input("");print(a)" ...


4

A little edit in your script: #!/bin/bash opts="OPTS=\"-name user -age 20 -where Asia -eats Brains\"" echo $opts ok="0" for word in $opts; do if [ "$ok" = "1" ] ; then echo $word break fi if [ "$word" = "-where" ] ; then ok="1" fi done


4

From vi you can type :cq to exit without saving and with a non-zero return code. In this case the command will not be repeated. Alternatively, you can usually suspend the editor with ctrl-z which gets you back to the shell without redoing the command. You still have to fg to restart the editor, but the tmp file will no longer be around, so you can safely ...


4

Replace "discription" by "description:" (typo and missing colon). RHEL 5 needs "chkconfig:" and "description:", RHEL6 only "chkconfig:".


3

Bash version 4 introduced built-in case-modification operators ^ and , operators, making it possible to avoid external programs like awk for such simple string manipulations if you have a recent version of the bash shell. In particular, if name=$(hostname) and path="path/to/" then "${path}${name^}" should concatenate the strings, with the first ...


3

No need for echo, no need for other other useless commands, single awk should do the job: $ xrandr | awk -F'[x ]' '/^ /{print $4"x"$5" \t"$4/$5}' 1024x600 1.70667 800x600 1.33333 640x480 1.33333


3

For the third version, you want "$*" not "$@". Explanation To illustrate, let's set some positional arguments: $ set -- arg1 arg2 arg3 Now, let's read them out with your echo formulation: $ printf "%s\n" "$(echo $@)" arg1 arg2 arg3 Let's see what "$@" does with them: $ printf "%s\n" "$@" arg1 arg2 arg3 The difference is that "$@" expands to three ...


3

There is two types of time commands. One is shell built-in, belongs to bash. That's the one you see in your first example. Second one , is /usr/bin/time, that's the second one you saw. As for why it's different output, it's because you cannot pipe output to shell builtins. More on that here


3

That part: echo "{@@##}RETURN_REAL_STATUS_SCRIPT=${?}" Just prints: {@@##}RETURN_REAL_STATUS_SCRIPT=x where the last x is replaces by the value of variable $?. From the bash manpage: ? Expands to the exit status of the most recently executed foreground pipeline. That means that $? contains the exit code of the previously executed command: ...


3

It's intended and documented in bash documentation, pattern matching section. The range expression [X-Y] will be included any characters between X and Y using the current locale’s collating sequence and character set: LC_ALL=en_US.utf8 bash -c 'case "b" in [A-Z]) echo yes; esac' yes You can see, b sorted between A and Z in en_US.utf8 locale. You have ...


2

This script copies the ip address from field 3 using awk to the start of the line with a "%" separator, then does the sort on the ip address now in the first field, then removes the added part. awk '{print $3 " % " $0}' | sort -t. -n -k1,1 -k2,2 -k3,3 -k4,4 | sed 's/[^%]*% //' If the field with the ip address is not a constant, you can auto-detect it on ...


2

Consider a simpler example to see the difference: $ set "a b" c "d e" $ printf "%s\n" "$@" a b c d e The preceding is what you should use; it's simple, easy to understand, and correct. $ printf "%s\n" "$(echo $@)" a b c d e Here, $@ first expands unquoted (the quotes surrounding the command substitution are separate and not yet applied), so it's ...


2

If it must be with echo "Kate", use awk: echo "Kate" | awk 'NR==FNR{a=$0;next} sub("Steven", a, $0)1' - file The standard input is Kate from echo "Kate", piped to awk. awk then reads the stdin (-). The condition NR==FNR is true when the first file is processes (stdin). The variable a is set to that value. Then the input of file is processed and sub() ...


2

You are asking the wrong question, or asking the question wrongly and in the wrong stack, this is a better question to ask in the programming/stack-overflow for people to give you answers based on the algorithms used inside awk and sort. PS: also do the needed with nawk, mawk and gawk to give us some more details to "zone into" ;) and do the runs like a 100 ...


2

You can try ps aux | awk 'NR>1{tot[$1]++;} END{for(id in tot)printf "%s %s\n",id,tot[id]}'


2

ps -fo user | sort | uniq -c is worth a try. The command ps -eo user=|sort|uniq -c will list process counts by user. ps -eo user=|sort|uniq -c 2 avahi 1 kernoops 1 messagebus 1 nobody 231 root 1 statd 5 steve 1 syslog If flipping the column order to read is required, pipe it through awk '{ print $2 " " $1 ...


2

Use unzip -p? unzip -p archive.zip 2015-05-05-raspbian-wheezy.img | dd of=/dev/sdb bs=1M


2

There's always the caveman approach: first=1 for i do if [ "$first" ] then first= continue fi something with "$i" done This leaves $@ intact (in case you want to use it later), and simply loops over every argument, but doesn't process the first one.



Only top voted, non community-wiki answers of a minimum length are eligible