Sample Header Ad - 728x90

Unix & Linux Stack Exchange

Q&A for users of Linux, FreeBSD and other Unix-like operating systems

Latest Questions

66 votes
5 answers
77086 views
What is "declare" in Bash?
After reading ilkkachu's answer to [this question][1] I learned on the existence of the `declare` (with argument `-n`) shell built in. `help declare` brings: > Set variable values and attributes. > > Declare variables and give them attributes. If no NAMEs are given, > display the attributes and valu...
After reading ilkkachu's answer to this question I learned on the existence of the declare (with argument -n) shell built in. help declare brings: > Set variable values and attributes. > > Declare variables and give them attributes. If no NAMEs are given, > display the attributes and values of all variables. > -n ... make NAME a reference to the variable named by its value I ask for a general explanation with an example regarding declare because I don't understand the man. I know what is a variable and expanding it but I still miss the man on declare (variable attribute?). Maybe you'd like to explain this based on the code by ilkkachu in the answer: #!/bin/bash function read_and_verify { read -p "Please enter value for '$1': " tmp1 read -p "Please repeat the value to verify: " tmp2 if [ "$tmp1" != "$tmp2" ]; then echo "Values unmatched. Please try again."; return 2 else declare -n ref="$1" ref=$tmp1 fi }
user149572
Apr 3, 2019, 06:49 AM • Last activity: Jun 11, 2025, 10:39 AM
2 votes
1 answers
2229 views
Zsh: timeout for vared builtin
I've got a while loop that uses [`vared`](http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#index-vared) to prompt for user input. I am looking for a way to have it timeout, execute a default variable and loop back to the prompt if there is not user input after a certain amount of time. I...
I've got a while loop that uses [vared](http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#index-vared) to prompt for user input. I am looking for a way to have it timeout, execute a default variable and loop back to the prompt if there is not user input after a certain amount of time. I am aware of the read command and its timeout argument, but is this somehow possible with vared? Also, is there a way to set a default for vared that doesn't print to the prompt? local command while : do echo "Enter a command or type 'quit' to exit:" vared -p "[*]: " command if [ "$command" = "quit" ]; then break else run command fi clear done
Кафка (161 rep)
Feb 4, 2020, 12:42 PM • Last activity: Sep 30, 2024, 07:05 AM
1 votes
3 answers
310 views
How to tail continuously a log file that is being deleted and recreated?
I need to extract information from a log file that is deleted and recreated every time a program runs. After detecting that the file exists (again), I would like to `tail` it for a certain regexp. The regexp will be matched a few times, but the result is always the same and I want to print it just o...
I need to extract information from a log file that is deleted and recreated every time a program runs. After detecting that the file exists (again), I would like to tail it for a certain regexp. The regexp will be matched a few times, but the result is always the same and I want to print it just once and after that go back to monitoring when the file is re-created. I looked at ways of detecting file creation. One way would be via inotifywait , but that requires installing a separate package. Perhaps a simpler way is to take advantage that tail prints to stderr when a file that is being tailed is deleted and created: tail: '/path/to/debug.log' has become inaccessible: No such file or directory tail: '/path/to/debug.log' has appeared; following new file So I applied this solution which is working: debug_file="/path/to/debug.log" while true; do # Monitor the log file until the 'new file' message appears ( tail -F $debug_file 2>&1 & ) | grep -q "has appeared; following new file" # After the new file message appears, switch to monitoring for the regexp tail -F "$debug_file" | while read -r line; do id=$(echo "$line" | sed -n 's/.* etc \([0-9]\+\),.*/\1/p') if [ -n "$id" ]; then echo "ID: $id" break # Exit the inner loop after the first match fi done done But I don't like that this solution starts 2 different tail processes. Is there a way to achieve the same result, but using just 1 tail process? And then switch 'modes', start by looking for file creation, then look for the regexp and once that is found go back to 'standby' mode waiting for the log file to be deleted and created again. Is inotifywait a more elegant solution? Ideally I would like a solution I could port easily to Windows CMD.
user2066480 (173 rep)
Mar 19, 2024, 05:27 PM • Last activity: Mar 20, 2024, 12:16 PM
0 votes
1 answers
143 views
Is a newline equivalent to && in a bash script?
I'm very simply wondering if, in a bash script, a new line is functionally 100% equivalent to `&&`? e.g.: ``` #!/bin/bash 7z x "${file}" mv "${file}" "${new_file}" ``` vs ``` #!/bin/bash 7z x "${file}" && mv "${file}" "${new_file}" ``` GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
I'm very simply wondering if, in a bash script, a new line is functionally 100% equivalent to &&? e.g.:
#!/bin/bash

7z x "${file}"

mv "${file}" "${new_file}"
vs
#!/bin/bash

7z x "${file}" && mv "${file}" "${new_file}"
GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
s.k (511 rep)
Mar 9, 2024, 07:10 PM • Last activity: Mar 9, 2024, 10:20 PM
5 votes
5 answers
2269 views
Multiple Command List After Shell Conditionals, &&, ||. Shell Script, Dash
I'm trying to do multiple commands after a condition, so for example... [ $VAR ] || echo "Error msg" ; echo "exit" and the Inverse [ -z $VAR ] && echo "Error msg" ; echo "exit" I know that won't work as intended, I actually knew how previously and forgot how to do this. I'm fully aware of the many a...
I'm trying to do multiple commands after a condition, so for example... [ $VAR ] || echo "Error msg" ; echo "exit" and the Inverse [ -z $VAR ] && echo "Error msg" ; echo "exit" I know that won't work as intended, I actually knew how previously and forgot how to do this. I'm fully aware of the many alternatives, such as using if's or bracketing via () and {} . Using () will create a sub process which wouldn't exit a running script. Using {} will work, but I know a more readable alternative exists. I have done this with a :, and it was perfect!!! I just can't remember now for the life of me, and I lost that previously written script. If anyone knows how to write this with the :'s, I would really appreciate any help!
J. M. Becker (5049 rep)
Dec 27, 2011, 04:10 AM • Last activity: Nov 19, 2023, 12:07 PM
2 votes
4 answers
143 views
How to execute a command after the previous non-terminating command prints a certain string?
I want to execute `commandA` which prints the following: ```none line1 line2 line3 started successfully line4 ... ... ``` And when the line `started successfully` is printed I want to start another command (and possibly multiplex their outputs so that both are printed on the terminal). How could I a...
I want to execute commandA which prints the following:
line1
line2
line3
started successfully
line4
...
...
And when the line started successfully is printed I want to start another command (and possibly multiplex their outputs so that both are printed on the terminal). How could I achieve this in bash?
Marinos An (889 rep)
Aug 1, 2023, 01:00 PM • Last activity: Oct 5, 2023, 05:01 PM
4 votes
2 answers
26078 views
How to use user input as a while loop condition
I can do this in bash: while read -n1 -r -p "choose [y]es|[n]o" do if [[ $REPLY == q ]]; then break; else #whatever fi done which works but seems a bit redundant, can i do something like this instead? while [[ `read -n1 -r -p "choose [y]es|[n]o"` != q ]] do #whatever done
I can do this in bash: while read -n1 -r -p "choose [y]es|[n]o" do if [[ $REPLY == q ]]; then break; else #whatever fi done which works but seems a bit redundant, can i do something like this instead? while [[ read -n1 -r -p "choose [y]es|[n]o" != q ]] do #whatever done
razzak (297 rep)
Sep 7, 2015, 10:50 PM • Last activity: Sep 21, 2022, 02:14 PM
5 votes
3 answers
962 views
Tool to detect errors in application's execution logic
I want to detect errors in application's execution logic. E.g.: - forgot to call `free()` on address returned by `malloc()` - did not close file handle returned by `open()` - invalid flags passed to `open()` - invalid file handle passed to `poll()` - `write()` called on fd that wasn't opened for wri...
I want to detect errors in application's execution logic. E.g.: - forgot to call free() on address returned by malloc() - did not close file handle returned by open() - invalid flags passed to open() - invalid file handle passed to poll() - write() called on fd that wasn't opened for writing - pass invalid flags to open() e.g. open("/etc/fstab", 4) - calling close() on an invalid fd - ... I think there are hundreds more. Maybe the tool can be run similar to ftrace or strace, but a kernel log containing the faulty calls would be sufficient too.
zomega (1012 rep)
Jul 6, 2022, 09:30 AM • Last activity: Jul 7, 2022, 04:35 PM
0 votes
0 answers
28 views
How do I get this code to evaluate all arms of if-else? Why does Bash seem to interpret the characters that I input as integers?
The last `elif` arm does not get executed: ``` #!/usr/bin/bash searches=("feet" "axilas" "lactant") length=${#searches[@]} searchFunction() { echo "Enter the respective number to go for the specific search. Otherwise type 'a' to loop through all of them." read i if [[ $i -lt $length && $i -gt -1 ]]...
The last elif arm does not get executed:
#!/usr/bin/bash


searches=("feet"
"axilas"
"lactant")

length=${#searches[@]}


searchFunction() {
  echo "Enter the respective number to go for the specific search. 
  Otherwise type 'a' to loop through all of them."
  read i
  if [[ $i -lt $length && $i -gt -1 ]] ; then 
    echo "within range"
    exit 0
  elif [[ $i -ge $length || $i -lt 0 ]] ; then
    echo "Your choice is out of range. Exiting."
    exit 0
  elif [[ $i == 'a' ]]; then
    echo "todo" #this does not get executed, why so?
  fi }



echo "The following are the search terms:"

for index in "${!searches[@]}"
do
  echo ${index} ${searches[index]}
done

searchFunction
When I switch the order of evaluation and add else, like so:
searchFunction() {
  echo "Enter the respective number to go for the specific search. 
  Otherwise type 'a' to loop through all of them."
  read i
  if [[ $i == 'a' ]]; then
    echo "todo" 
  elif [[ $i -lt $length && $i -gt -1 ]] ; then 
    echo "within range"
    exit 0
  elif [[ $i -ge $length || $i -lt 0 ]] ; then
    echo "Your choice is out of range. Exiting."
    exit 0
  else
    exit 0
  fi }
then the code works almost as intended ("todo" gets echoed but the issue is that when other non-numeric characters are given it prints "within range"). Why does Bash seem to interpret the characters that I input as integers? How might I improve on this?
John Smith (23 rep)
Feb 16, 2022, 09:52 AM • Last activity: Feb 16, 2022, 10:17 AM
578 votes
10 answers
1070880 views
How to conditionally do something if a command succeeded or failed
How can I do something like this in bash? if "`command` returns any error"; then echo "Returned an error" else echo "Proceed..." fi
How can I do something like this in bash? if "command returns any error"; then echo "Returned an error" else echo "Proceed..." fi
Shinmaru
Oct 16, 2011, 09:25 PM • Last activity: Jan 10, 2022, 04:14 PM
92 votes
6 answers
334465 views
How to loop over the lines of a file?
Say I have this file: hello world hello world This program #!/bin/bash for i in $(cat $1); do echo "tester: $i" done outputs tester: hello tester: world tester: hello tester: world I'd like to have the `for` iterate over each line individually ignoring whitespaces though, i.e. the last two lines sho...
Say I have this file: hello world hello world This program #!/bin/bash for i in $(cat $1); do echo "tester: $i" done outputs tester: hello tester: world tester: hello tester: world I'd like to have the for iterate over each line individually ignoring whitespaces though, i.e. the last two lines should be replaced by tester: hello world Using quotes for i in "$(cat $1)"; results in i being assigned the whole file at once. What should I change?
Tobias Kienzler (9574 rep)
Feb 7, 2011, 10:28 AM • Last activity: Nov 21, 2021, 09:34 PM
0 votes
0 answers
15 views
my if statement is returning command not found
in my script an if statement returns: line 3: []: command not found the statement: ``` if ["$(pidof -x $(basename $0) -o %PPID)"]; then echo process already running; exit; fi ``` what I tried: ``` if [["$(pidof -x $(basename $0) -o %PPID)"]]; then echo process already running; exit; fi ``` ``` if [[...
in my script an if statement returns: line 3: []: command not found the statement:
if ["$(pidof -x $(basename $0) -o %PPID)"]; then
    echo process already running; exit;
fi
what I tried:
if [["$(pidof -x $(basename $0) -o %PPID)"]]; then
    echo process already running; exit;
fi
if [["$(pidof -x basename $0 -o %PPID)"]]; then
    echo process already running; exit;
fi
if ["$(pidof -x basename $0 -o %PPID)"]; then
    echo process already running; exit;
fi
if [[$(pidof -x basename $0 -o %PPID)]]; then
    echo process already running; exit;
fi
none seems to work.I get similar error. line 3: [[]]: command not found I got the code from here: https://linuxpip.org/rclone-examples/ https://forum.rclone.org/t/continuous-syncing/12377/2 I did research here: https://wiki.bash-hackers.org/syntax/ccmd/conditional_expression and looked at the man bash’s Compound Commands section but they don’t seem to help. please help Thank you!
andy (1 rep)
Oct 18, 2021, 04:15 AM
441 votes
3 answers
228811 views
What are the shell's control and redirection operators?
I often see tutorials online that connect various commands with different symbols. For example: command1 | command2 command1 & command2 command1 || command2 command1 && command2 Others seem to be connecting commands to files: command1 > file1 command1 >> file1 What are these things? What are they ca...
I often see tutorials online that connect various commands with different symbols. For example: command1 | command2 command1 & command2 command1 || command2 command1 && command2 Others seem to be connecting commands to files: command1 > file1 command1 >> file1 What are these things? What are they called? What do they do? Are there more of them? ---- [Meta thread about this question.](https://unix.meta.stackexchange.com/q/3177/22222) .
terdon (251585 rep)
Oct 6, 2014, 02:18 AM • Last activity: Sep 30, 2021, 01:13 PM
6 votes
1 answers
7328 views
if ! <command> (...) vs. <command> ; if [ $? -eq 0 ] (...)
I am working on a shell script and decided to check my work via [shellcheck.net][1]. I am able to get functionally the same behavior of the following two lines in my script: findmnt /dev/sda1 >/dev/null ; if [ $? -eq 0 ]; then echo 1; else echo 0; fi vs. if ! findmnt /dev/sda1 >/dev/null; then echo...
I am working on a shell script and decided to check my work via shellcheck.net . I am able to get functionally the same behavior of the following two lines in my script: findmnt /dev/sda1 >/dev/null ; if [ $? -eq 0 ]; then echo 1; else echo 0; fi vs. if ! findmnt /dev/sda1 >/dev/null; then echo 0; else echo 1; fi However shellcheck throws : > SC2181: Check exit code directly with e.g. 'if mycmd;', not indirectly > with $?. It is not immediately clear to me which to use. I do see: https://github.com/koalaman/shellcheck/issues/1167 which seems to have amended this for several possible values. I want to be sure that I am writing something that uses best practices and will run without issue and report accurately.
Kahn (1827 rep)
Sep 28, 2021, 06:45 PM • Last activity: Sep 28, 2021, 07:47 PM
109 votes
9 answers
151164 views
Press space to continue
How do I stop a bash script until a user has pressed Space ? I would like to have the question in my script > Press space to continue or CTRL + C to exit and then the script should stop and wait until Space is pressed.
How do I stop a bash script until a user has pressed Space? I would like to have the question in my script > Press space to continue or CTRL+C to exit and then the script should stop and wait until Space is pressed.
rubo77 (30435 rep)
Jun 4, 2014, 10:42 AM • Last activity: Sep 3, 2021, 07:12 AM
6 votes
2 answers
3204 views
[ vs [[ : which one to use in bash scripts?
The zsh man page, in its section on `test` (aka `[`), explicitly advises against using it at all, and urges readers to use `[[` whenever possible. The [relevant section][1] states: > The command attempts to implement POSIX and its extensions where these are specified. Unfortunately there are intrins...
The zsh man page, in its section on test (aka ), explicitly advises against using it at all, and urges readers to use [[ whenever possible. The [relevant section states: > The command attempts to implement POSIX and its extensions where these are specified. Unfortunately there are intrinsic ambiguities in the syntax; in particular there is no distinction between test operators and strings that resemble them. The standard attempts to resolve these for small numbers of arguments (up to four); for five or more arguments compatibility cannot be relied on. Users are urged wherever possible to use the '[[' test syntax which does not have these ambiguities. I think I've come across similar advice for bash, but as I scan over the bash man page I can't find any "official" recommendation there on which form ([ or [[) to use. (Maybe I missed it?) >Is there any reason, *other than backward compatibility with "older shells"*, for using [ in a bash script? Or to put it differently, does bash keep [ along with [[ for reasons *other* than backward compatibility?
kjo (16299 rep)
Mar 7, 2013, 10:51 AM • Last activity: Sep 1, 2021, 04:01 PM
12 votes
3 answers
2241 views
Send task to background in an "if"
Why is this? if true; then sleep 3 &; fi bash: syntax error near unexpected token `;' I want to run sleep 3 in the background so that the command ["sleep 3" is just an example] would run in "paralell" style, so it finishes faster. But I'm getting this: bash: syntax error near unexpected token `;' er...
Why is this? if true; then sleep 3 &; fi bash: syntax error near unexpected token `;' I want to run sleep 3 in the background so that the command ["sleep 3" is just an example] would run in "paralell" style, so it finishes faster. But I'm getting this: bash: syntax error near unexpected token `;' error message. Why? Why can't I send a task to the background?
LanceBaynes (41465 rep)
Dec 10, 2011, 11:28 AM • Last activity: May 31, 2021, 05:12 PM
2 votes
1 answers
410 views
Executing a remote script from a code repository causes endless loop
I often execute raw versions of remote Bash scripts in GitHub with this pattern: wget -O - https://raw.githubusercontent.com/ / / / / | bash Generally I can do it without problems but since I have added the following code to a certain script I get an endless loop of `echo` (it often occurs even if I...
I often execute raw versions of remote Bash scripts in GitHub with this pattern: wget -O - https://raw.githubusercontent.com///// | bash Generally I can do it without problems but since I have added the following code to a certain script I get an endless loop of echo (it often occurs even if I just copy-paste it from GitHub to the terminal and execute directly):
while true; do
    read -p "Example question: Do you wish to edit the PHP file now?" yn
    case $yn in
        [Yy]* ) nano PROJECT/PHP_FILE; break;;
        [Nn]* ) break;;
        * ) echo "Please answer yes or no.";;
    esac
done
I can at least partly solve the problem with something like:
cd ACTION_DIRECTORY
wget https://raw.githubusercontent.com/////  &&
source FILENAME &&
rm FILENAME
Which indicates that the | bash piping at least worsens the problem because the problem **always** happens with it. Why would echo "Please answer yes or no." happen "endlessly"? (which I stop it with CTRLC+C)
Do you find any problem either in the single lined execution command and/or in the while true; do case esac done?
variable_expander (45 rep)
Mar 20, 2021, 05:32 AM • Last activity: Mar 20, 2021, 12:57 PM
0 votes
1 answers
30 views
Pausing script execution until user quits out of `less`
**Goal**: `less` the contents (from a variable) and then ask the user whether the contents should be saved to a file (i.e., `.recovered_object`) *only after* the user quits out of `less`. The excerpt from my script is reproduced below: ```zsh ... # Show each blob until one is chosen counter=1 while...
**Goal**: less the contents (from a variable) and then ask the user whether the contents should be saved to a file (i.e., .recovered_object) *only after* the user quits out of less. The excerpt from my script is reproduced below:
...
    # Show each blob until one is chosen
	counter=1
	while IFS='' read sha; do
		printf "Showing blob %d of %d" "$counter" "$BLOB_COUNT"
		contents=$(git show ${sha})
		${PAGER:-less} ${contents}
		if read -q '?Save and quit (y/n) ?'; then
			echo "$contents" > .recovered_object
			exit 0
		else
			((counter++))
		fi
	done <<< ${DANGLING_BLOBS_SHA}

    exit 0
As it stands now, any keypress (other than y) skips to the next file...but this precludes the user from scrolling up (k) or down (j) or using less's other keymappings! How do I prevent the if block from immediately running? --- PS: I'm pretty new to shell scripting in general, so any pointers are welcome. PSS: I am using zsh, but am not opposed to switching to bash if that's more conducive to achieving the desired UX.
Per48edjes (13 rep)
Mar 1, 2021, 03:01 AM • Last activity: Mar 1, 2021, 04:02 AM
0 votes
2 answers
331 views
How to modify and write to file before printing to STDERR
I am working on an automated pull request check via GitHub actions and I want to preserve some data from a command's `stderr` output between jobs. For this, I need to write the `stderr` to an *artifact* file, but before that I need to also remove some control chars from it via `sed`, otherwise I end...
I am working on an automated pull request check via GitHub actions and I want to preserve some data from a command's stderr output between jobs. For this, I need to write the stderr to an *artifact* file, but before that I need to also remove some control chars from it via sed, otherwise I end up with something like:
\x1b[31mFound 344 errors!\x1b[39;49m
I then want the main command to return the same exit code in order to fail the check and prevent merging of the pull request. I can probably take care of a subset of what needs doing, but am unable to take care of all 3 together together (sed > file write > stderr). If it makes it easier, I am okay with writing both stdout and stderr to the file as well. Open to suggestions to do this differently.
Abhishek Jain (119 rep)
Nov 28, 2020, 05:52 PM • Last activity: Dec 3, 2020, 10:46 AM
Showing page 1 of 20 total questions