Hot answers tagged

34

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 ...


18

In shells, exec does 1) file openings and redirections 2) actual execing (replacing the current process image with another process image). These execs are redirections. First you redirect (exec 1> >(tee $LOGFILE)) the stdout descriptor (1) to a process substitution-generated pipe connected to a concurrently run tee process that has $LOGFILE as its ...


10

I suggest you install fasd. It gives you the ability to quickly jump to any directory you've already been in by typing only a small fraction of its name. Example: if you've visited /home/someName/scripts/, you could jump there just by typing z scr for example. It's way more convenient that remembering the ordering in the history stack of anything similar.


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; ...


8

When you cd somewhere, Bash stores the old working directory an environment variable, $OLDPWD. You can switch back to that directory with cd -, which is equivalent to cd "$OLDPWD". You can bounce back and forth between directories like so: blue$ cd ~/green green$ cd - blue$ cd - green$


8

Save this to a file, let's say patterns.awk, then call awk -f patterns.awk patterns data, where patterns is your first file, and data the second: NR == FNR { prefix[NR] = $0; pattern[NR] = $2; count++; next; } { for (i = 1; i <= count; i++) { if (index($1, pattern[i]) > 0) { print prefix[i] " " $0; ...


7

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

That's not the here string, it's ANSI-C quoting: Words of the form $'string' are treated specially. ... The expanded result is single-quoted, as if the dollar sign had not been present. So what you've got is a single-quoted string to the right of <<<. That string gets taken as the here string, with no further processing. There's no need to ...


5

Use sort | uniq -c to count identical lines: find "$path" -type f -exec file -b {} + | sort | uniq -c | sort -nr


5

From the bash man page. When used with [[, the < and > operators sort lexicographically using the current locale. From the output, it appears to be working as designed.


4

Use a while loop: while read -r -p "Yes or no? " response && [[ $response =~ ^([yY][eE][sS]|[yY])$ ]] do ... done Or to make that code POSIX sh compatible so you don't need to have bash installed: while printf 'Yes or No? ' && read answer do case $answer in ([yY][eE][sS] | [yY]) ...;; (*) break;; esac done ...


4

You need to keep asking for a response until it isn't one you want: while true; do read -r -p "Yes or no? " response if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]] then echo "You chose yes" else exit 0 fi done


4

You can do this with indirection for progs in ${list[@]}; do a="${progs}_MIN_REQ" b="${progs}_CURR" echo "$progs: ${!a}:${!b}" done


4

I dont know if it is beautiful but it is working for every format of version that i know. #!/bin/bash currentver="$(gcc --version | head -n1 | cut -d" " -f4)" requiredver="5.0.0" if [ "$(printf "$requiredver\n$currentver" | sort -V | head -n1)" == "$currentver" ] && [ "$currentver" != "$requiredver" ]; then echo "Less than 5.0.0" else ...


4

I wrote a script named xyzzy to do this: #!/bin/bash i="$1" i=$((${i//[^0-9]/})) i="$(($i-1+0))" b="$2" b=$((${b//[^0-9]/})) b="$(($b-1+0))" if [ -z "$XYZZY_INDEX" ]; then XYZZY_INDEX="$((-1))" fi if [ ! -f "/tmp/xyzzy.list" ]; then touch /tmp/xyzzy.list chmod a+rw /tmp/xyzzy.list fi readarray -t MYLIST < /tmp/xyzzy.list showHelp(){ read ...


4

There is also cd_func from Peter Marinov, it's basically cd with a stack with up to 10 entries: http://linuxgazette.net/109/misc/marinov/acd_func.html # do ". acd_func.sh" # acd_func 1.0.5, 10-nov-2004 # petar marinov, http:/geocities.com/h2428, this is public domain cd_func () { local x2 the_new_dir adir index local -i cnt if [[ $1 == "--" ]]; ...


4

Use pushd and then the special names for the directories in your directory stack: ~1, ~2, etc. Example: tmp $ dirs -v 0 /tmp 1 /tmp/scripts 2 /tmp/photos 3 /tmp/music 4 /tmp/pictures tmp $ cd ~3 music $ dirs -v 0 /tmp/music 1 /tmp/scripts 2 /tmp/photos 3 /tmp/music 4 /tmp/pictures music $ cd ~2 photos $ cd ~4 pictures $ cd ~3 music $ cd ...


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

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 can, just enable extdebug and return a non-zero code (See the description of extdebug option) from myHandler: $ function myHandler() { if [[ $SKIP = "true" ]]; then return 1; fi; echo 'myHandler execute' } $ trap 'myHandler' DEBUG $ shopt -s extdebug $ echo 1 myHandler execute 1 $ SKIP=true myHandler execute $ echo 1


3

This is a bug in bash completion in dnf (not the first one and not the last one). Let's see what I can find out. Running the same with set -x will reveal the source of this: python3 -c 'import sys; from dnf.cli import completion_helper as ch; ch.main(sys.argv[1:])' _cmds sear -d 0 -q -C does not return the list of options, but basically some error. It ...


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

#! /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

Using sed with a string You have correctly identified the problem: $reg is a string, not a file. Thus, you need to supply the string to sed as stdin. Replace: reg1=$(sed /^Domain/d $reg) with (for bash): reg1=$(sed /^Domain/d <<<"$reg") Or, for a general POSIX shell, use: reg1=$(echo "$reg" | sed /^Domain/d) Simplification: combining the ...


3

The most likely cause for history items not to show up is not by setting HISTFILE to nothing or HISTSIZE to zero, it is by logging into the same machine twice and exiting with the second bash instance (in which you did little or nothing) after the one where you did a lot. By default Bash doesn't merge histories and the second Bash-exit overwrites the ...


3

These are all various forms of parameter expansion with alternatives: ${var:-val} is replaced by val if var is unset or null, ${var} otherwise (so val is a "default value"); ${var:=val} first assigns val to var if var is unset or null, and then (in all cases) is replaced by ${var}; ${var:+val} is replaced with nothing if var is unset or null, val ...


3

I use a small script called z, which might also be of interest, even though it does not do exactly what you asked. NAME z - jump around SYNOPSIS z [-chlrtx] [regex1 regex2 ... regexn] AVAILABILITY bash, zsh DESCRIPTION Tracks your most used directories, based on 'frecency'. After a short learning phase, z will take ...


3

I mostly use ZSH with oh-my-zsh profile. You can type into a terminal the following match: # cd /ho Then you can simply use arrows (up and down) to go through all the shell history which shows only those entries that start with the characters above. So, for instance, if you went to /home/morfik/Desktop/ and /home/morfik/something/, you can switch between ...



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