17

To clarify this, let me add add some debugging output to stderr (bypassing the pipe), before & after echoing "hop2": $ for test in test1 test2 test3; do (echo ${test}; sleep 4s; echo before hop2 >&2; echo hop2; echo after hop2 >&2; sleep 4s; echo hop3) | date; done Sat Apr 10 11:29:46 PDT 2021 before hop2 Sat Apr ...


12

In the beginning of your script, just touch a flag somewhere, so that subsequent invocations of that script can check for the existence and age of that flag. There's some ambiguity in your question. So first, let's assume that you're asking "How to make a script execute only if certain amount of time has passed since the last time the script executed.&...


12

Probably easiest to use tr to convert the zeroes from /dev/zero to whatever you want, and then cut to length using dd or head or such. This would write 18520 bytes with all bits ones, so value 0xff or 255, or 377 in octal as the input must be: < /dev/zero tr '\000' '\377' | head -c 18520 > test.bin (To convert from hex or decimal to octal, you could ...


12

Don't use dd bs=…: it isn't reliable. Either use ibs=1 obs=1 or use less error-prone tools. Most head implementations can count bytes: </dev/zero head -c 18520 If you want a file filled with a single byte other than zero, change the byte value with tr. For all-bits-one: </dev/zero head -c 18520 | tr '\0' '\377'


11

By default, interactive bash shells have history expansion enabled (which is what controls the behaviour of !). Sourced files (which exist largely outside of the concept of history expansion) and scripts do not. From man bash (or the online manual): set [--abefhkmnptuvxBCEHPT] [-o option-name] [arg ...] -H: Enable ! style history substitution. This option ...


10

The shell's arithmetic doesn't support chained comparisons like that. Instead, the first a < b returns either 1 or 0, depending on if the relation is true or not. So, if k is 0, then ((0 < k < 1)) is ((0 < 0 < 1)), the same as (( (0 < 0) < 1)) because of left-association. Zero is not less than zero, so 0 < 0 is falsy, so in an ...


9

(echo ${test}; ...) | date What are you trying to do here? You're piping data to the stdin of date, but date doesn't read any input. It just prints the date and exits. After date exits, the pipe closes, after which any data printed to it has nowhere to go and the process writing to the pipe, the subshell (echo; sleep; echo; sleep), gets sent the SIGPIPE ...


8

Yes, &> is a bash operator (now also supported by zsh, while zsh always had >& for the same like in csh), and >(...) a ksh operator (now also supported by zsh and bash), neither are sh operator. That unquoted $LOG_FILE where you obviously don't want split+glob here, makes it zsh syntax (the only one of those shells where split+glob is not ...


8

Your (internal) RedHat system administrators will be able to do this for you. It's a trivial operation, something like this yum install ksh The system default shell and the shell used to run your scripts does not have to be the same. The shebang line tells your system which interpreter (which shell) to use to run a given script. Bear in mind, though, that ...


7

When you run a command like sudo echo some text > file the redirection is done by your shell as the normal user before running sudo. Edit, answering a comment: The shell doesn't treat sudo as anything specific compared to other commands, and it doesn't know that sudo will run with elevated privileges. The shell's behavior will be the same as with /bin/...


7

For whatever reason, it is obfuscated in two layers. The first script creates a second similar script that it runs with eval. The second script creates a third script that it evals. This is the start of the third and final script (indented by me for readability): pkg install pulseaudio dir=$(pwd) if grep -q "anonymous" ~/../usr/etc/pulse/default....


6

The [...] is a bracket expression. It matches a single character, always, so you can't use [0-100] as that would just match a single 0 or 1 (in the POSIX locale) In the zsh shell, you could use <0-100> for a numerical range globbing pattern, but that won't work in bash: program --files path_to_mydir/mydata_<0-100>.csv In bash, you could use a ...


6

I'd do #!/usr/bin/env bash die () { echo "$*" >&2; exit 1; } input=$1 [[ $input == +([[:digit:]]) ]] || die "only digits please" (( input <= 9999 )) || die "no more than 4 digits please" echo "ok: $input"


6

If you care about the number of digits (and not the numerical value), you could match against a regex in Bash/Ksh/Zsh: #!/bin/bash input=$1 re='^[[:digit:]]{1,4}$' if [[ $input =~ $re ]]; then echo "'$input' contains 1 to 4 digits (and nothing else)" else echo "'$input' contains something else" fi Or e.g. [[ $input =~ ^[[:digit:]]...


6

Here assuming you mean ASCII decimal digits only and not other sorts of decimal or non-decimal digits. shopt -s extglob # enables a subset of ksh extended globs including *(...), # +(...) and ?(...) but unfortunately not {4}(...) d='[0123456789]' nd='[^0123456789]' case $input in ( $d$d$d$d+($d) ) echo made of more than 4 digits;; (...


5

Simplest is largely a matter of opinion, but I feel the simplest way to do this is to use cron. You will need some other "ingredients" to accomplish your objective, but cron can serve as the scheduler for starting a script at boot time. This assumes the version of cron on your system offers the @reboot facility; see man 5 crontab to verify the &...


5

What you can do is turn the comparison around: case "example" in "$1"*) echo OK ;; *) echo Error ;; esac With multiple words, you can stick with your original idea case "$1" in e|ex|exa|exam|examp|exampl|example) : ;; t|te|tes|test) : ;; f|fo|foo) : ;; *) echo error ;; esac or use a loop and a "boolean" ...


5

The parameter expansion ${variable:-value} will expand to the string value if the variable variable is unset or empty. This is a standard parameter expansion that is not special to the bash shell, but that works in all POSIX-compatible shells. The special variable $* is a string consisting of the positional parameters concatenated with the first character ...


5

If you want to examine the number of characters a variable, you can do this... var="foo bar" echo "var contains ${#var} characters" Result: var contains 7 characters


5

It's an argument to the function: note the $1 part in the echo string: that is the first argument being used by the bash function. Try running the function with varying arguments, e.g. cursorBack 5, or even cursorBack foo, to see what happens. Note that the first part of the echo command is an ANSI escape, followed by the function argument (a number), ...


5

This seems to match the description of -e/-errexit in the bash documentation: The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test in an if statement, part of any command executed in a && or || list except the command following the final && or ||, any ...


4

The reason this is complicated is that scripts run in their own sub-shell: a copy of your current environment. So any variables a script sets are discarded as soon as the script exits and returns you to your original shell. However, since it is indeed important to be able to set variables this way, there is a tool for that. You are looking for the . (or ...


4

You could consider using anacron. Anacron allows scheduling periodic jobs on computers that are not turned on all the time. To achieve this, it maintains so-called timestamp files that record the last time a job was run. When the computer is on, anacron regularly gets triggered via various mechanisms (startup script, regular cron jobs, systemd timers) and ...


4

I found another solution that still uses sqlite3 .import, but that doesn't read /dev/stdin or a temporary named pipe. Instead, it uses .import with the pipe operator to invoke cat - to read directly from standard input. #!/bin/bash function csv_to_sqlite() { local database_file_name="$1" local table_name="$2" sqlite3 -csv $...


4

There is nothing to send to date as it receives no data on stdin. So, using a | is simply incorrect. I believe that you need to use && instead. But the question: Why the time interval between each output is four seconds instead of eight? Is still valid, but confusing to explain. The short answer is that the commands after echo hop2 never get executed....


4

From the manual [emphasis mine]: errexit Same as -e. -e Exit immediately if a pipeline […], which may consist of a single simple command […], a list […], or a compound command […] returns a non-zero status. The shell does not exit if the command that fails is part of […] any command executed in a && or || list except the command following the final ...


4

exec script.sh replaces the current shell with the one defined in the shebang line of script.sh, and uses that interpreter to run the rest of the file. This could be anything from /bin/sh to /usr/bin/python, no matter what the filename extension is. To do this, script.sh has to be executable. One of the side effects of this is that when script.sh is done the ...


4

Just start Quodlibet in the current shell, not in a sub-process: #!/bin/bash trap "exit" INT TERM ERR trap "kill 0" EXIT (sleep 2 && conky) & quodlibet [update] You mention that you want to run this script from a .desktop file in a graphical environment. @fra-san made me aware that every process run this way are likely to ...


3

The behavior of sh is specified by POSIX. A Linux system may have a variety of shells which are used as /bin/sh, including but not limited to bash, dash, mksh, or ash, and while each of these may have custom mechanisms for implementing behavior in this case, the only thing you can rely on across all of them is what POSIX specifies. The way to specify a ...


3

The [...] glob operator, like the similar regexp operator matches a character (or possibly collating element) in the specified set. It only matches one character. Inside [...], you can have individual characters, like [abc] which matches on either a or b or c character classes, like [[:digit:]] which matches on characters for which isdigit() returns true. ...


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