Hot answers tagged

18

The sed command, the awk command, and the removal of the trailing period can all be combined into a single awk command: while read -r host; do dig +search "$host" ALL; done <hostlist.txt | awk 'f{sub(/.$/,"",$1); print $1", "$NF; f=0} /ANSWER SECTION/{f=1}' Or, as spread out over multiple lines: while read -r host do dig +search "$host" ALL done ...


12

The short answer is: you don't, but it saves about 1ms of CPU time (on modern CPUs). (Note that you should exec only at the end of a script, because nothing after the exec will get run). The longer answer is: Exec replaces the process image of the current process with the process image of the executable you exec. That means that the moment you exec, the ...


11

bash's builtin pushd with the + and - options can rotate the directory stack. The syntax can be a little confusing, perhaps because that stack is a zero-based array. These simple wrapper functions cycle through the directory stack: # cd to next directory in stack (left rotate) ncd(){ pushd +1 > /dev/null ; } # cd to previous directory in stack ...


10

It should be #!/usr/local/bin/osh if your shell is in /usr/local/bin. If /usr/local/bin is on your PATH then #!/usr/bin/env osh should work too... (In fact that's the only point of env here — it will find osh wherever it's installed, as long as it's on the PATH, so it doesn't matter if it's in /usr/local/bin, /usr/bin etc. The first one found wins if ...


8

expr is archaic. Don't use it. $((...)) and ((...)) are very similar. Both do only integer calculations. The difference is that $((...)) returns the result of the calculation and ((...)) does not. Thus $((...)) is useful in echo statements: $ a=2; b=3; echo $((a*b)) 6 ((...)) is useful when you want to assign a variable or set an exit code: $ a=3; ...


7

dig can read in a file containing a list of hostnames and process them one by one. You can also tell dig to suppress all output except the answer section. This should give you the output you want: dig -f hostlist.txt +noall +answer +search | awk '{sub(/\.$/,"",$1); print $1","$5}' awk's sub() function is used to strip the literal period . from the ...


6

Change your invocation of gawk to the following: | gawk '{print substr($1,1,length($1)-1)","$NF}' >fqdn-ip.csv


6

Just run: long-command & sleep 300; do-this-after-five-minutes The do-this-after-five-minutes will get run after five minutes. The long-command will be running in the background.


5

POSIX says of uniq -u: Suppress the writing of lines that are repeated in the input. which means that any line which is repeated (even the original line) will be filtered out. What you meant was probably (done with POSIX also): sort -u results.db For sort -u, POSIX says Unique: suppress all but one in each set of lines having equal keys. If ...


4

You can use timeout command to run your command or script in a given timeout. Something similar to this: timeout 10m command Which waits for the command to finish withing 10 minutes otherwise kills it and exits with status 124. Then you can check exit status of timeout and print the appropriate message based on it. See here for more: timeout manpage. If ...


4

You need to run the script instead of sourcing it: /path/to/script.sh (without .). When you run . /path/to/script.sh $0 is your current shell, which is presumably in /bin (hence the behaviour you're seeing). Note that it needn't be /bin/bash, the shebang doesn't have any effect when sourcing a script. Lucas' other points are valid, you should use ...


4

The simplest solution is: for dir in *; do mv "$dir"/v2.3.0/* "$dir"/; done To only move php files use: for dir in *; do mv "$dir"/v2.3.0/*php "$dir"/; done And to avoid error messages if you have files (an not only directories) in the top level: for dir in *; do [ -d "$dir" ] && mv "$dir"/v2.3.0/* "$dir"/; done


4

That's because you have a space between the path and the $1. Try this instead: function chef(){ /opt/chefdk/embedded/bin/"$1" }


4

Here is a sample script which you can use to implement this: #!/bin/bash shopt -s extglob readonly URL="https://google.com" links=($(grep -o -P '(?<=href=").*(?=")' source.html)) # read into array for ((i=0; i<${#links[@]}; i++)) do case ${links[$i]} in http*) : # do nothing ;; /*) links[$i]="$URL"${links[$i]}; # update ...


4

Use bc or awk or a shell with floating point support like ksh93, zsh or yash instead of bash. bc $ bc -l << \EOF heredoc> for (i = 0; i <= 10; i += 2.5) i / 2 heredoc> EOF 0 1.25000000000000000000 2.50000000000000000000 3.75000000000000000000 5.00000000000000000000 awk $ awk 'BEGIN {for (i = 0; i <= 10; i += 2.5) print i / 2}' 0 1.25 ...


3

for i in {15360..15871}; do printf "2607:f4a0:3:0:250:56ff:feac:%.4x\n" $i; done Output: 2607:f4a0:3:0:250:56ff:feac:3c00 2607:f4a0:3:0:250:56ff:feac:3c01 2607:f4a0:3:0:250:56ff:feac:3c02 2607:f4a0:3:0:250:56ff:feac:3c03 . . . 2607:f4a0:3:0:250:56ff:feac:3dfd 2607:f4a0:3:0:250:56ff:feac:3dfe 2607:f4a0:3:0:250:56ff:feac:3dff


3

This is a terminal independent way of enabling the blinking attribute. If it doesn't work then either you've mis-set your terminal type, it's not enabled in the terminal characteristics, or it's simply not supported: tput blink echo hello, world tput sgr0 The terminfo database is well worth perusing (not bedtime reading, mind) to find semi-readable names ...


3

There is a BIG difference. Lets take the following script called testscript: #!/bin/ksh #im testscript cd /proc/$$ file exe First lets execute it with ./: $ ./testscript exe: symbolic link to /bin/ksh93 Now calling bash: $ bash testscript exe: symbolic link to /bin/bash Do you see the difference? The interpreter used by the script changed in the ...


3

You could use this script: #!/bin/bash TEMPFILE="$(mktemp)" STARTTIME="$(date +%s)" (./longprocess; rm -f "$TEMPFILE") & while [ -f "$TEMPFILE" ]; do sleep 1s NOW="$(date +%s)" if (( (NOW-STARTTIME) % 300 == 0 )); then echo "$(( (NOW-STARTTIME)/60 )) minute(s) elapsed" fi done echo "Done!!!" It executes your longprocess in a ...


3

You could use RANDOM variable defined by bash: URL=${URLLIST[ $(( RANDOM % ${#URLLIST[@]} )) ] } where URLLIST is the an array containng your urls: URLLIST=( \ "http://xkcd.com/archive" \ "http://what-if.xkcd.com/" \ "http://blag.xkcd.com/" \ "http://store.xkcd.com/" \ )


3

You just need to escape the $ character, as in echo "\${STR1}" >> myfile or echo "\$STR2" >> myfile Alternatively, you can use single quotes echo '${STR1}' '$STR2'


3

The variable $0 points to the shell script that you execute itself. So if you have a file in that contains this #!/bin/sh echo "$0" and copy it to /bin/my-script and to ~/somewhere/my-script-2, make both copies executable you can observe this behavior (I assume /bin is in your $PATH): $ my-script /bin/my-script $ ~/somewhere/my-script-2 ...


3

Instead of reading hoption, rspid and rspname from stdin while the script is running, you should take them as options on the command line, just like most other programs do. This sounds difficult, but is actually quite easy using the bash-builtin getopts (see help getopts for a summary) That way you can easily test your script with the same args just by ...


3

#! /bin/bash ( sleep 4 ) & # <-- The long running process. seconds=1 while jobs %1 &>/dev/null ; do echo $((seconds++)) seconds complete sleep 1 done echo Done. jobs %1 fails once the job %1 has stopped. Note that for longer times, $seconds might get out of sync with the real time. It's better to store the start time and ...


3

There is a one liner for this: ( ( sleep $TIMEOUT ; echo "5 minutes complete") & $COMMAND ) In your case TIMEOUT=5m and COMMAND is the long command. Also see my answer to this post Timeout with 'service network restart'


3

With gsed you don't need the extra '', only with the default OSX sed. Try with either: SED=/usr/bin/sed Or: SEDOPTS=(-i)


3

try (u being your file) sort -n -t\| -k2 -k1 < u | awk -F\| '$1 < 8000 { a[$2]++ ; print } $1 >= 8000 { if ( !a[$2] && ( !e[$2] || e[$2]<$8 )) {u[$2]=$0;e[$2]=$8;} ; } END { for ( i in u ) print u[i] ;}' gives 4000|1234||||||23 5000|1234||||||40 15000|456||||||29 9000|123||||||22 where -t\| and -F\| ...


2

Add a debug line of echo ${hoption} after it reads it in to confirm it is being set correctly. Also put an echo in each case indicating you've reached that case. In this case since you are only looking for a single character, I would use read in this way: read -r -n 1 hoption The -n 1 flag tells read to only wait for 1 character and not wait for a new ...


2

Single find command will output all the files with absolute path find $(pwd) -type f


2

I came up with two options using diff that should work for you. Using diff -u and sed: diff -u old new | sed -n 's/^-\(.*\.so\..*\)/\1/p' /usr/lib/libfoo.so.1 /usr/lib/libfooabc.so.1 That command outputs the full diff between the two files, and we use sed to filter out only the changes from the 'old' file (indicated by a leading -), and further filter ...



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