Tag Info

Hot answers tagged

19

No, you certainly don't want to close file descriptors 0, 1 and 2. If you do so, the first time the application opens a file, it will become stdin/stdout/stderr... For instance, if you do: echo text | tee file >&- When tee (at least some implementations, like busybox') opens the file for writing, it will be open on file descriptor 1 (stdout). So ...


16

! inverts the exit status of the command -- it's part of POSIX shell syntax, it's not part of if. From the POSIX spec: If the reserved word ! does not precede the pipeline, the exit status shall be the exit status of the last command specified in the pipeline. Otherwise, the exit status shall be the logical NOT of the exit status of the last command. ...


11

Have grep read on its standard input. There you go, using a pipe... $ echo "$line" | grep select ... or a here string... $ grep select <<< "$line" Also, you might want to replace spaces by newlines before grepping : $ echo "$line" | tr ' ' '\n' | grep select ... or you could ask grep to print the match only: $ echo "$line" | grep -o select ...


10

It is a boolean operator that equates to the logical not. See man bash: ! expression     True if expression is false. In your example, if not foo, echo blah.


8

First, note that the single slash matches too much: $ echo $'eegg \n e.g.' | grep e\.g\. eegg e.g. As far as Bash is concerned, an escaped period is the same as a period. Bash passes on the period to grep. For grep, a period matches anything. Now, consider: $ echo $'eegg \n e.g.' | grep e\\.g\\. e.g. $ echo $'eegg \n e.g.' | grep e\\\.g\\\. e.g. $ ...


7

IOW I have always wondered if >/dev/null means that cat mybigfile >/dev/null would actually process every byte of the file and write it to /dev/null which forgets it. It's not a full answer to your question, but yes, the above is how it works. cat reads the named file(s), or standard input if no files are named, and outputs to its standard output ...


6

Just to add to the other answers, the code uses ! to avoid writing the code like this: if foo ; then # everything that used to follow "fi" in the previous version else echo "blah" exit 1 fi That only works if there is something after the fi in the script, since an empty if clause isn't legal. (A comment doesn't count.) Writing it this way ...


5

You're having problems because your shell is trying to expand * into the list of files, but it can't since you don't have rights to read the directory. I can think of two things that would work sudo bash -c "rm directory/*" In this case, the * isn't expanded by you, but by root, who can read the directory OR sudo find directory -type f -exec rm {} \; ...


4

getopt is perfectly fine with having no short options. But you need to tell it that you have no short options. It's a quirk in the syntax — from the manual: If no -o or --options option is found in the first part, the first parameter of the second part is used as the short options string. That's what's happening in your test: getopt -l long-key -- ...


4

will a script have different behaviour depending on what type of shell is executing it. In the sense that bash script.sh and ksh script.sh are likely to behave differently, yes. Commonly, that difference will be that one of them works and one gives an error, but there are a range of options. Many simple scripts will have the same behaviour on common ...


4

The output is the same only for your string, but in general those regular expressions do different things. Let's modify your example a little by adding second pattern e,g, (with comas), third e\.g\. (dots), fourth e\,g\, (comas), and -o option to grep to print only matched parts. In the following case . match any char (notice '' around e.g., I will come to ...


3

test=$line i=0 while case "$test" in (*select*) test=${test#*select};;(*) ! :;; esac; do i=$(($i+1)); done You don't need to call grep for such a simple thing. Or as a function: occur() while case "$1" in (*"$2"*) set -- \ "${1#*"$2"}" "$2" "${3:-0}" "$((${4:-0}+1))";; (*) return "$((${4:-0}<${3:-1}))";;esac do : ...


3

Commands within your prompt command function alter PIPESTATUS, bash saves and restores PIPESTATUS (and $?) after your prompt command, see the description of the intended behaviour here. The trick is to save $PIPESTATUS[] (and/or $?) in the very first statement of your function, after that the original values are overwritten. function myprompt() { ...


3

The >-sign represents an I/O-Redirection. With >stat.txt you redirect the standard output (stdout) of the application to the file stat.txt. It is redirected, so you will not see any output in the shell. If you want the output in the current shell AND the file pipe the output into tee: your_command | tee stat.txt Or.. your_command | tee -a stat.txt ...


3

It's possible that the output is being sent to stderr which is not captured by the > operator which only captures stdout. Instead, if you are using the bash shell, try routing stderr to stdout and into a file using the &> operator. For example: unpackdcm -scr ${in} -targ ${out} &>stat.txt To redirect only stderr, use this: unpackdcm ...


3

When you do a grep e\.g\., the shell is consuming the backslash, thus you are doing a grep e.g., which matches. When you do a grep e\\.g\\., the shell is again consuming a slash, and now you are doing a grep e\.\g., which again matches. Now, a backslash to the shell looks like \\. So, when you have \\, the first one is an escape sequence, the second is a ...


3

ffmpeg -i "stream_link" -codec copy -f mpegts - -codec copy -f flv - | myprogram -h 127.0.0.1 -p 12345 -f - | myprogram -h 127.0.0.1 -p 12345 -f - So If I understand correctly, you are tryithisng to combine these 2 commands into one. mpegts format ffmpeg -i "stream_link" -codec copy -f mpegts - | myprogram -h 127.0.0.1 -p 12345 -f - flv format ...


3

There is a way in bash 4.3+, which probably comes from ksh: echo_idx_array () # array index { local -n array=$1 # add nameref attribute local idx=$2 echo "${array[idx]}" } $ names=(one two three four) $ echo_idx_array names 2 three $ days=([monday]=eggs [tuesday]=bread [sunday]=jam) # associative array $ echo_idx_array days sunday jam ...


2

If you're fine with the optional arguments being at the end, you can just do this: foo=$1 bar=$2 baz=${3:-default value} That will store the first two arguments in $foo and $bar. If a third argument was provided, it will be stored in $baz; otherwise it will default to default value. You can also just check if the third variable is empty: if [ -z "$3" ]; ...


2

You were close, but you should use single quotes, not double quotes: kill_stopped='kill `jobs -p` ' Backticks are expanded inside double quotes, so it was running jobs -p at the time you defined the alias, not when you used it.


2

awk ' function to_seconds(hms, t) { split(hms, t, /:/) return (t[1]*3600 + t[2]*60 + t[3]) } $2 in times {print to_seconds($1) - times[$2], $2} {times[$2] = to_seconds($1)} ' << DATA 19:32:19 4599544 19:32:22 4599544 19:33:07 4599545 19:33:11 4599545 19:33:58 4599546 19:34:01 ...


1

Given the fact your arrays only have one element and that you test a constant variable, your script, as it is written is equivalent to: #!/bin/sh bridge="gbr0" CSIF="eth2" echo Starting service bridge $bridge brctl addbr $bridge || RETVAL=1 brctl stp $bridge on brctl setbridgeprio $bridge 65000 echo Adding CSIF $CSIF on $bridge ifup $CSIF brctl addif ...


1

Try this: alias kill_stopped="kill \$(jobs -p)" and to kill runnings jobs: kill_stopped If there are no running jobs you get a message about the usage of the kill.



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