Sample Header Ad - 728x90

Unix & Linux Stack Exchange

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

Latest Questions

220 votes
8 answers
44353 views
Why is looping over find's output bad practice?
This question is inspired by [_Why is using a shell loop to process text considered bad practice ?_][1] I see these constructs for file in `find . -type f -name ...`; do smth with ${file}; done and for dir in $(find . -type d -name ...); do smth with ${dir}; done being used here almost on a daily ba...
This question is inspired by _Why is using a shell loop to process text considered bad practice ?_ I see these constructs for file in find . -type f -name ...; do smth with ${file}; done and for dir in $(find . -type d -name ...); do smth with ${dir}; done being used here almost on a daily basis even if some people take the time to comment on those posts explaining why this kind of stuff should be avoided... Seeing the number of such posts (and the fact that sometimes those comments are simply ignored) I thought I might as well ask a question: *Why is looping over find's output bad practice and what's the proper way to run one or more commands for each file name/path returned by find ?*
don_crissti (85483 rep)
Nov 7, 2016, 06:22 PM • Last activity: Apr 19, 2025, 09:44 AM
0 votes
1 answers
85 views
How to batch compress pdfs?
I'm looking to batch compress some pdfs, using the convert to/from ps trick outlined elsewhere. I have a function defined in an .zshrc file: ``` function pdfcompress() { for f in "$1"; do echo "compressing $1" pdf2ps "$f" "$f".ps ps2pdf -dPDFSETTINGS=/default "$f".ps "$f" rm "$f".ps done } ``` My un...
I'm looking to batch compress some pdfs, using the convert to/from ps trick outlined elsewhere. I have a function defined in an .zshrc file:
function pdfcompress() {
	for f in "$1"; do
		echo "compressing $1"
		pdf2ps "$f" "$f".ps
		ps2pdf -dPDFSETTINGS=/default "$f".ps "$f"
		rm "$f".ps
	done
}
My understanding is that I should be able to pass this a list of pdfs, and it compresses them. However, the following happens:
% ls | pdfcompress
compressing
Error: /undefinedfilename in --findlibfile--
Operand stack:
   ()
Execution stack:
   %interp_exit   .runexec2   --nostringval--   findlibfile   --nostringval--   2   %stopped_push   --nostringval--   findlibfile
   findlibfile   false   1   %stopped_push   findlibfile   1815   1   3   %oparray_pop   findlibfile
Dictionary stack:
   --dict:743/1123(ro)(G)--   --dict:0/20(G)--   --dict:85/200(L)--
Current allocation mode is local
GPL Ghostscript 10.04.0: Unrecoverable error, exit code 1
GPL Ghostscript 10.04.0: Device 'pdfwrite' requires an output file but no file was specified.
**** Unable to open the initial device, quitting.
It seems that none of the file names are getting passed, for some reason. I've also tried approaches with find . -iname "*.pdf" -exec pdfcompress, and piping to xargs pdfcompress, but neither of those work because the function isn't in the environment. Other times the placeholder variables seem to be interpreted as literal strings. I've been trying to get this to work in some form for over an hour with no luck. Any tips? I have a folder structure of pdfs that I would like to maintain, so a solution that works recursively within directories would be best, if possible. Thank you!
sporkl (103 rep)
Feb 21, 2025, 08:26 PM • Last activity: Feb 22, 2025, 06:13 PM
0 votes
1 answers
38 views
terraform resource dependency with count(loop)
I'm trying to create stack of multiple vms on KVM_HOST with terraform. The catch is, I'm using pxeboot & kickstart to do installation. Kickstart file needs to carry some dynamic information, like static IPs, hostname etc, therefore I have to create it for each vm, and this kickstart file needs to st...
I'm trying to create stack of multiple vms on KVM_HOST with terraform. The catch is, I'm using pxeboot & kickstart to do installation. Kickstart file needs to carry some dynamic information, like static IPs, hostname etc, therefore I have to create it for each vm, and this kickstart file needs to stay there till vm reads it & starts installation. Then next kickstart file is created for vm 2, and it needs to stay there till vm2 reads it for installation. So there should be some delay in creating these resources, either with loop or depend_on parameter, but what I'm getting is, kickstart files for all vms are generated right away, last one is overriding, of course, so correct info is not passed. here's two resources which I need to loop in sequence for number of variable value qty
variable "vm_count" {
  type    = number
  default = 1
}
below are resources
resource "null_resource" "delay" {
  count = var.vm_count

  provisioner "local-exec" {
    command = "sleep 150"
  }
  depends_on = [libvirt_domain.vm]
}

resource "local_file" "kickstart_file" {
  count = var.vm_count
  content = templatefile("ks.tpl", {
    ip                = "192.168.1.${117 + count.index}"
    netmask           = var.netmask
    gateway           = var.gateway
    dns               = var.dns
    hostname          = "${var.hostname}-${count.index + 1}"
    disk_size_rounded = ((var.disk_size - 1) * 1024) -1
  })
  filename = "/var/www/html/kickstart/ks-terraform.cfg"
}

resource "libvirt_domain" "vm" {
  count  = var.vm_count
  name   = "${var.hostname}-${count.index + 1}"
  memory = var.memory
  vcpu   = var.cpu
  arch   = "x86_64"

  cpu {
    mode = "host-passthrough"
  }

  boot_device {
    dev = ["hd", "network"]
  }

  disk {
    volume_id = libvirt_volume.default_disk[count.index].id
  }

  graphics {
    type        = "vnc"
    listen_type = "address"
    autoport    = true
  }

  network_interface {
    bridge = "virbr0"
    macvtap  = false
  }

  depends_on = [local_file.kickstart_file, null_resource.delay]
}
how can I improve the logic with depends on or for_each?
Sollosa (1993 rep)
Feb 11, 2025, 02:11 PM • Last activity: Feb 11, 2025, 07:18 PM
0 votes
2 answers
1678 views
for loop in FreeBSD (pfSense) doesn't work
I've just noticed that the same code for `for loop` in bash doesn't work in FreeBSD wolf@linux:~$ echo $SHELL /bin/bash wolf@linux:~$ wolf@linux:~$ for i in {1..3}; do echo $i; done 1 2 3 wolf@linux:~$ Is there any alternative for this? [2.5.0-RELEASE][admin@pfSense]/root: echo $SHELL /etc/rc.initia...
I've just noticed that the same code for for loop in bash doesn't work in FreeBSD wolf@linux:~$ echo $SHELL /bin/bash wolf@linux:~$ wolf@linux:~$ for i in {1..3}; do echo $i; done 1 2 3 wolf@linux:~$ Is there any alternative for this? [2.5.0-RELEASE][admin@pfSense]/root: echo $SHELL /etc/rc.initial [2.5.0-RELEASE][admin@pfSense]/root: [2.5.0-RELEASE][admin@pfSense]/root: for i in {1..3}; do echo $i; done for: Command not found. i: Undefined variable. [2.5.0-RELEASE][admin@pfSense]/root:
Wolf (1741 rep)
Mar 7, 2021, 12:11 PM • Last activity: Oct 17, 2024, 05:05 AM
3 votes
2 answers
1841 views
How to extract and delete contents of a zip archive simultaneously?
I want to download and extract a large zip archive (>180 GB) containing multiple small files of a single file format onto an SSD, but I don't have enough storage for both the zip archive and the extracted contents. I know that it would be possible to extract and delete individual files from an archi...
I want to download and extract a large zip archive (>180 GB) containing multiple small files of a single file format onto an SSD, but I don't have enough storage for both the zip archive and the extracted contents. I know that it would be possible to extract and delete individual files from an archive using the zip command as mentioned in the answers [here](https://unix.stackexchange.com/questions/14120/extract-only-a-specific-file-from-a-zipped-archive-to-a-given-directory) and [here](https://superuser.com/questions/600385/remove-single-file-from-zip-archive-on-linux) . I could also get the names of all the files in an archive using the
-l
command, store the results in an array as mentioned [here](https://www.baeldung.com/linux/reading-output-into-array) , filter out the unnecessary values using the method given [here](https://stackoverflow.com/questions/9762413/bash-array-leave-elements-containing-string) , and iterate over them in BASH as mentioned [here](https://www.cyberciti.biz/faq/bash-for-loop-array/) . So, the final logic would look something like this: 1. List the zip file's contents using
-l
and store the filenames in a bash array, using regular expressions to match the single file extension present in the archive. 2. Iterate over the array of filenames and successively extract and delete individual files using the
-j -d
and
-d
commands. How feasible is this method in terms of time required, logic complexity, and computational resources? I am worried about the efficiency of deleting and extracting single files, especially with such a large archive. If you have any feedback or comments about this approach, I would love to hear them. Thank you all in advance for your help. **Edit 1:** It seems this question has become a bit popular. Just in case anyone is interested, here is a BASH script following the logic I have outlined earlier, with batching for the extraction and deletion of files to reduce the number of operations. I have used DICOM files in this example but this would work for any other file type or for any files whose file names can be described by a regular expression. Here is the code:
#!/bin/bash

# Check if a zip file is provided as an argument
if [ -z "$1" ]; then
  echo "Usage: $0 "
  exit 1
fi

zipfile=$1

# List the contents of the zip file and store .dcm files in an array
mapfile -t dcm_files < <(unzip -Z1 "$zipfile" | grep '\.dcm$')

# Define the batch size
batch_size=10000
total_files=${#dcm_files[@]}

# Process files in batches
for ((i=0; i
The file would have to be saved with a name like
.sh
with a
.sh
extension and marked as executable. If the script and archive are in the same folder and the name of the archive is
.zip
, the method to run the script would be
./inplace_extractor.sh archive.zip
. Feel free to adjust the batch size or the regular expression or account for any subfolders in your archive. I tried it with my large archive and the performance was absolutely abysmal while the disk space rapidly shrunk, so I would still recommend going with the approaches suggested in other answers.
Kumaresh Balaji Sundararajan (51 rep)
Nov 12, 2023, 12:24 PM • Last activity: Oct 5, 2024, 11:37 AM
6 votes
2 answers
7547 views
How to exit a bash loop by keyboard input?
I have a `bash lopp` as #!/bin/bash for (( c=0; c<=1000000; c++ )) do SOME STUFF HERE done I interrupt the long loop by a keyboard input like `Ctrl+C` but `Ctrl+C` simply terminates the script. I am looking for an alternative to continue the current cycle and break the loop after finishing the runni...
I have a bash lopp as #!/bin/bash for (( c=0; c<=1000000; c++ )) do SOME STUFF HERE done I interrupt the long loop by a keyboard input like Ctrl+C but Ctrl+C simply terminates the script. I am looking for an alternative to continue the current cycle and break the loop after finishing the running STUFF in the current cycle.
Googlebot (2009 rep)
Apr 27, 2017, 10:25 PM • Last activity: Jul 26, 2024, 02:12 PM
2 votes
1 answers
166 views
Not working break in for loop in bash script for mounting a VHD
I'm not an experienced programmer. So maybe it's obvious for you why the break command in this script does not terminate the loop, but I can't see what is causing the problem. I want to use the script to mount a VHD file to the first empty NBD "slot" (which is assumed when it's size is zero, I took...
I'm not an experienced programmer. So maybe it's obvious for you why the break command in this script does not terminate the loop, but I can't see what is causing the problem. I want to use the script to mount a VHD file to the first empty NBD "slot" (which is assumed when it's size is zero, I took this idea from another thread on this site).
function vhdmount() {
 workfile="$1"
 if test -e "$workfile"
 then
  workname=${workfile##*'/'}
  echo "$(tput setaf 3)*** ${workfile}: ***$(tput setaf 7)"
  for (( i=0; i<16; i++ ))
  do (
   if test -e /sys/class/block/nbd${i}/size
   then
    usedornot=$( cat /sys/class/block/nbd${i}/size )
    if (( "$usedornot" == 0 ))
    then
     firstfree=$i
     break
    fi
   else
    firstfree=$i
    break
   fi
  ); done
  sudo modprobe nbd
  sudo qemu-nbd -c /dev/nbd${firstfree} "$workfile"
  sudo mkdir "/media/myusername/${workname//.vhd/.nbd${firstfree}}/"
  sudo mount /dev/nbd${firstfree}p1 "/media/myusername/${workname//.vhd/.nbd${firstfree}}/"
  echo "$(tput setaf 3)    successfully mounted.$(tput setaf 7)"
 fi
}

vhdmount "$1"
Maybe there are other errors as well. I'm always terminating the shell when it asks for the password, because I can tell from the 16 messages telling me that a break command is only useful in a for loop that the break command did not work. By the way, what a useless error message is that?!
Shakesbeer (123 rep)
Jun 24, 2024, 10:03 AM • Last activity: Jun 24, 2024, 10:32 AM
0 votes
1 answers
59 views
using a variable which has content separated by spaces in shell in a for loop
I am trying to read a variable with spaces on prompt and trying to use in a for loop., For example: ```none Enter the items to read separated by space... apple orange kiwi ``` ```sh read items for i in "$items" do echo $i ...(additional operations).... done ``` But shell does take the first item - a...
I am trying to read a variable with spaces on prompt and trying to use in a for loop., For example:
Enter the items to read separated by space...  
apple orange kiwi
read items  

for i in "$items"  
do  
echo $i  
...(additional operations)....  
done
But shell does take the first item - apple here. What am I missing here.
sabarish tr (1 rep)
May 8, 2024, 09:27 PM • Last activity: May 8, 2024, 11:06 PM
-1 votes
1 answers
73 views
Output of loop variable shows different value than expected
Imagine I have two folders in my current working directory: `back/` and `front/`. I am trying to enter inside each of them and do some stuff. From the simple script below: ```lang-shell for dir in */ ; do echo "$(dir)" done ``` I was expecting an output like: ```none back front ``` However, what I a...
Imagine I have two folders in my current working directory: back/ and front/. I am trying to enter inside each of them and do some stuff. From the simple script below:
-shell
for dir in */ ; do
    echo "$(dir)"
done
I was expecting an output like:
back
front
However, what I am getting is:
back  front
back  front
I don't understand. The consequence is that, if I try to cd into the folder:
-shell
for dir in */ ; do
    echo "$(dir)"
    cd $(dir)
    echo "$(pwd)"
    cd ..
done
I get:
back  front
/path/to/back
back  front
/path/to/back
I.e. I never enter front/. Could someone please help me understand what I am doing wrong?
Rigel F. do C. (1 rep)
Apr 22, 2024, 03:06 PM • Last activity: Apr 24, 2024, 12:50 PM
-3 votes
4 answers
191 views
How to catch all lines of a repeating pattern and do some actions with the subresults
I am looking for a possibility to catch in a repeating text pattern all variable amount of lines between them and then do an action with it in bash. Example text: ``` Total: text1 text2 Total: text3 Total: Text1 Text4 Text5 ``` What I am aiming to do is basically a for loop over the matches with `To...
I am looking for a possibility to catch in a repeating text pattern all variable amount of lines between them and then do an action with it in bash. Example text:
Total:
text1
text2
Total:
text3
Total:
Text1
Text4
Text5
What I am aiming to do is basically a for loop over the matches with Total: and then do an action with it, which is always going to be the first section of the follow-up subtext. Something like in high level language: for (cat filename = every "Total:" do end Now the interesting part for me is basically how to organize that for loop? In the ` part I want do some jq and awk`. The results would be basically based on the example text these three matches: 1.
Total:
text1
text2
2.
Total:
text3
3.
Total:
Text1
Text4
Text5
Hope the last description describes it. What could be the right tool for catching this? Would that be rather a combination of for and grep or for and awk? I would like to use no more than GNU tools. So no perl or other external tools. Thanks a lot.
Andr&#233; Letterer (9 rep)
Apr 2, 2024, 04:01 PM • Last activity: Apr 3, 2024, 12:34 PM
4 votes
2 answers
460 views
SSH for loop: parameter passed to function captured in variable is not expanded
I have several servers which have several files with deploy date info I need to parse, and get a local copy of the files which are 2 months old or older. ```bash #!/bin/bash # split on new line not space # don't want to quote everything # globbing desired IFS=$'\n' servers=( blue red ) parseDate() {...
I have several servers which have several files with deploy date info I need to parse, and get a local copy of the files which are 2 months old or older.
#!/bin/bash

# split on new line not space
# don't want to quote everything
# globbing desired
IFS=$'\n'

servers=(
  blue
  red
)

parseDate() {
    grep 'deploy_date:' $file | \
    sed  ...                  | \
    # much more in here...
}

getOldFiles() {
    local #all vars
    currentDateInSecs=$(date +%s)
    twoMonthsInSecs=526000
    for server in ${servers[@]}; do
        oldfile=$(
          ssh $server "
            $(declare -f parseDate)
            for file in /dir/$server/file*; do
                dateInSecs=$(date -jf '%b/%e/%Y' $(parseDate) +%s)
                timeDiff=$((\$currentDateInSecs - \$dateInSecs))
                ((\$timeDiff >= \$twoMonthsInSecs)) &&
                    cat \$file
            done
          "
        )
        [ -n $oldFile ] &&
            cat $oldFile ~/oldFiles/${server}-${file}.txt
    done
### Problem: Current issue is with dateInSecs=$(date -jf '%b/%e/%Y' $(parseDate \$file) +%s). When parseDate \$file is in $() the $file variable is not expanded, it works fine without command substitution, but I need it. How do I fix this? ### Info: This isn't a script, they're in my ~/.bash_profile This is a script (among other scripts) in a git repo which is sourced from ~/bash_profile (I have an install script which sets sources using $PWD) so people can use these commands directly instead of cd'ing to the git repo (which has many other things not applicable to the them). Runs from Macos to CentOS servers.
Nickotine (554 rep)
Jan 30, 2024, 05:26 PM • Last activity: Feb 2, 2024, 05:33 PM
0 votes
2 answers
322 views
How to run for loop over SSH on remote so that variables expand?
If I `ls` files without a for loop in a remote host everything is fine however, if I capture the `ls` in a variable and try to `echo` each file it fails as the variables don't expand/have a value. What I mean: ```bash IFS=$'\n' servers=( blue green red ) ``` ```bash for i in ${servers[@]}; do ssh $i...
If I ls files without a for loop in a remote host everything is fine however, if I capture the ls in a variable and try to echo each file it fails as the variables don't expand/have a value. What I mean:
IFS=$'\n'
servers=(
  blue
  green
  red
)
for i in ${servers[@]}; do 
   ssh $i "
     ls /dir/xyz_${i}*/details.txt
   "
done
/dir/xyx_blue0/details.txt 
/dir/xyz_blue1/details.txt
/dir/xyx_green2/details.txt 
/dir/xyz_green4/details.txt
/dir/xyx_red1/details.txt 
/dir/xyz_red8/details.txt
But I actually need to loop through the output of ls so I can do things to the files, however the variable doesn't expand:
for i in ${servers[@]}; do 
   ssh $i "
     for i in $(ls /dir/xyz_${i}*/details.txt); do 
        echo $i
     done
   "
done
not found: /dir/xyx_blue*/details.txt 
not found: /dir/xyx_green*/details.txt 
not found: /dir/xyx_red*/details.txt
How can I get $i to expand when running a loop on the remote host?
Nickotine (554 rep)
Jan 29, 2024, 11:48 PM • Last activity: Jan 31, 2024, 02:04 PM
0 votes
2 answers
2459 views
Shell script with a for loop and an “array”
How can I use this shell script with for loop and an array. I would like to call create condition for quality gate creation of sonarqube with a for loop. Example: ``` #!/bin/bash --login echo "Creating SonarQube Gateway Condition" QG_ID=$(cat qualitygate.json | jq -r ".id") Gateway="curl -u ${USERNA...
How can I use this shell script with for loop and an array. I would like to call create condition for quality gate creation of sonarqube with a for loop. Example:
#!/bin/bash --login

echo "Creating SonarQube Gateway Condition"

QG_ID=$(cat qualitygate.json | jq -r ".id")
Gateway="curl -u ${USERNAME}:${PASSWORD} -k -X POST "${SONAR_HOST_URL}/api/qualitygates/create_condition?"
declare -a gateMetrics=("gateId=$QG_ID&metric=coverage&op=LT&error=80\"" "gateId=$QG_ID&metric=duplicated_lines_density&op=GT&error=10\"")

for val in "${gateMetrics[@]}"
do
  echo $Gateway$val
done
I want the output as below after running above command
curl -u ${USERNAME}:${PASSWORD} -k -X POST "${SONAR_HOST_URL}/api/qualitygates/create_condition?gateId=$QG_ID&metric=coverage&op=LT&error=80"
user1628 (11 rep)
Jan 25, 2021, 08:09 AM • Last activity: Dec 17, 2023, 07:03 AM
0 votes
2 answers
297 views
Pass multiple arguments from single line from a text file to teminal
I have a python program that requires 2 arguments input-file and output-file. It reads input-file and creates a copy of that file with some modifications in the output-file. I created a text file with a set of arguments. It has multiple sets of arguments on multiple lines. But for 1 execution of a p...
I have a python program that requires 2 arguments input-file and output-file. It reads input-file and creates a copy of that file with some modifications in the output-file. I created a text file with a set of arguments. It has multiple sets of arguments on multiple lines. But for 1 execution of a program it needs to read line by line. So each line has 2 args (separated by a space) to be passed: input-file and output-file. Example of file with arguments (call it *File-With-Multiple-Arguments-Per-Line.txt*): input-file-1-path/input-file-1-name.sql output-file-1-path/output-file-1-name.sql input-file-2-path/input-file-2-name.sql output-file-2-path/output-file-2-name.sql input-file-3-path/input-file-3-name.sql output-file-3-path/output-file-3-name.sql input-file-4-path/input-file-4-name.sql output-file-4-path/output-file-4-name.sql I tried this: for arg in $(` But using "$arg" "$arg" leads to incorrect interpretation of my program. As if does the same task 3 times - first time does what is intended; second time using input-file as output and input; third time using output-file as output and input. I've tried the solution below as well, but then my program does not do anything. Though it displays the output in my terminal as if it did what was supposed to be done. And no error appears. For reference: https://unix.stackexchange.com/questions/429834/reading-multiple-arguments-for-a-shell-script-from-file while read x y; do python /Users/Git-Repos/MyProgram.py "$x" "$y" done < /Users/Repository/File-With-Multiple-Arguments-Per-Line.txt
Data Engineer (113 rep)
Nov 3, 2023, 12:15 AM • Last activity: Nov 3, 2023, 04:55 PM
1 votes
1 answers
1591 views
csh: redirecting output from foreach
In csh: How do I redirect the output from a `foreach`-loop to a pipe? This works but uses a temp file: set tmpfile=/tmp/file true > $tmpfile foreach v (`set | awk -e '{print $1}' |grep -v prompt2`); eval if'($?'$v' && ${#'$v'} > $tmpfile eval if'($?'$v' && ${#'$v'} > 1) echo array'$v'="$'$v'"' >> $t...
In csh: How do I redirect the output from a foreach-loop to a pipe? This works but uses a temp file: set tmpfile=/tmp/file true > $tmpfile foreach v (set | awk -e '{print $1}' |grep -v prompt2); eval if'($?'$v' && ${#'$v'} > $tmpfile eval if'($?'$v' && ${#'$v'} > 1) echo array'$v'="$'$v'"' >> $tmpfile end cat $tmpfile | parallel --shellquote | perl -pe 's/^scalar(\S+).=/set $1=/ or s/^array(\S+).=(.*)/set $1=($2)/;' I would like to get rid of the temp file and use a pipe instead. So something like this (does not work): ( foreach v (set | awk -e '{print $1}' |grep -v prompt2); eval if'($?'$v' && ${#'$v'} 1) echo array'$v'="$'$v'"' end ) | parallel --shellquote | perl -pe 's/^scalar(\S+).=/set $1=/ or s/^array(\S+).=(.*)/set $1=($2)/;'
Ole Tange (37348 rep)
Oct 4, 2015, 02:32 PM • Last activity: Oct 31, 2023, 08:34 PM
2 votes
1 answers
1792 views
Make whiptail work in a for loop
I have a bash script that checks ping for 163 sites(stores around the country), which is this: #!/bin/bash #storestest.sh #version 0.9.2 clear; printf "Check stores procedure started; `date +"%d/%m/%Y %H:%M:%S"`\n"; declare -a STORESITE=($(cat 'stores.txt' | awk -F, '{print $1}')); # Declaring an ar...
I have a bash script that checks ping for 163 sites(stores around the country), which is this: #!/bin/bash #storestest.sh #version 0.9.2 clear; printf "Check stores procedure started; date +"%d/%m/%Y %H:%M:%S"\n"; declare -a STORESITE=($(cat 'stores.txt' | awk -F, '{print $1}')); # Declaring an array and populated by the file stores.txt declare -i UP=0; # Create a variable to serve as a counter for stores that are up declare -i DOWN=0; # Create a variable to serve as a counter for stores that are down touch storesdown.txt; # Create a file if does not exist to store the list of the store the stores that are down printf "" > storesdown.txt; # Clear the contents of the file touch storesup.txt; # Create a file if does not exist to store the list of the store the stores that are up printf "" > storesup.txt; # Clear the contents of the file whiptail --title "Testing stores connectivity" --backtitle "Store Test" --yes-button "OK" --no-button "Cancel" --yesno "Check stores procidure has started" 10 50 if [ $? -ne 0 ]; then exit; fi for i in "${STORESITE[@]}" ; do ping -c 3 $i > /dev/null 2> /dev/null; if [ $? -eq 0 ]; then echo "$i is up" >> storesup.txt; let UP++ sleep 1 else echo "$i is down" >> storesdown.txt; let DOWN++ sleep 1 fi printf "Total: $UP are online and $DOWN are off line.\r"; done echo "Total: $UP are online and $DOWN are off line."; exit; The above script is working fine but I decided to make it a bit fancier by adding a gauge to show the total progress of it. So here is what I did next: #!/bin/bash #storestest.sh #version 0.9.3 clear; printf "Check stores procedure started; date +"%d/%m/%Y %H:%M:%S"\n"; declare -a STORESITE=($(cat 'stores.txt' | awk -F, '{print $1}')); # Declaring an array and populated by the file stores.txt declare -i UP=0; # Create a variable to serve as a counter for stores that are up declare -i DOWN=0; # Create a variable to serve as a counter for stores that are down touch storesdown.txt; # Create a file if does not exist to store the list of the store the stores that are down printf "" > storesdown.txt; # Clear the contents of the file touch storesup.txt; # Create a file if does not exist to store the list of the store the stores that are up printf "" > storesup.txt; # Clear the contents of the file whiptail --title "Testing stores connectivity" --backtitle "Store Test" --yes-button "OK" --no-button "Cancel" --yesno "Check stores procidure has started" 10 50 if [ $? -ne 0 ]; then exit; fi total="${#STORESITE[*]}"; { for ((g = 0; g /dev/null 2> /dev/null; if [ $? -eq 0 ]; then echo "$i is up" >> storesup.txt; let UP++ sleep 2 else echo "$i is down" >> storesdown.txt; let DOWN++ sleep 2 fi printf "Total: $UP are online and $DOWN are off line.\r"; done sleep 1 echo $g done } | whiptail --gauge "Please wait" 6 60 0 echo "Total: $UP are online and $DOWN are off line."; exit; Which does not work as I thought it should be.... That was the best way I could think and write to make at least the whiptail work, but apparently what it happens is to skip the nested loop. P.S I know some of my coding is obsolete and old fashion way of bash scripting.
ChrisH (21 rep)
Nov 25, 2015, 01:32 AM • Last activity: Oct 26, 2023, 05:08 PM
1 votes
2 answers
2218 views
Is there a syntax for a "for" loop over words or lines in a variable, that will work unmofdified in both bourne shell and zsh?
I have a variable that contains a list of strings, one per line, to be looped over in a `for...in...do...done` command. I move regularly between bourne shell and zsh. As far as I can understand it, zsh doesnt by default split words out of a a string at newline or whitespace; bourne shell does. So co...
I have a variable that contains a list of strings, one per line, to be looped over in a for...in...do...done command. I move regularly between bourne shell and zsh. As far as I can understand it, zsh doesnt by default split words out of a a string at newline or whitespace; bourne shell does. So commands like for list_item in $list; do... fail in zsh whereas they'd work in bourne shell, or with literal text rather than variable. Ive tried playing with IFS= in the command, and quoting the variable, but can't seem to make progress. Is there a single syntax for a loop over the words/lines in the string, that will work unmodified in both shells, for ease? if not, what's best practice?
Stilez (1311 rep)
Oct 14, 2023, 10:46 AM • Last activity: Oct 19, 2023, 02:04 PM
0 votes
3 answers
3012 views
What is the proper way to loop through each directory in a for loop?
For example, in this for loop ``` for var in ????? do dummy command done ``` I would like to be able to loop through each directory in the one that I am currently in, but it will be an unknown list of directories so I can't write every single one into where the question marks are. Any help is apprec...
For example, in this for loop
for var in ?????
do
    dummy command
done
I would like to be able to loop through each directory in the one that I am currently in, but it will be an unknown list of directories so I can't write every single one into where the question marks are. Any help is appreciated.
Anonymous (11 rep)
Jun 8, 2020, 05:24 PM • Last activity: Aug 25, 2023, 12:34 PM
3 votes
4 answers
2426 views
execute a command recursively on the files of a folder in the matching location, not in the original one
I want to recursively convert files from `.docx` to `.doc` in a folder. The problem is that all the output files are created in the folder where I run the following command, not in the location of the source files: find -type f -name "*.docx"-exec libreoffice --convert-to doc {} \; I understand that...
I want to recursively convert files from .docx to .doc in a folder. The problem is that all the output files are created in the folder where I run the following command, not in the location of the source files: find -type f -name "*.docx"-exec libreoffice --convert-to doc {} \; I understand that find gives source files to the libreoffice command and the output obviously has to be in the current location, so how can I use a command to loop recursively into a folder and execute the command from the location where the files is found, not the initial one?
fich (340 rep)
Oct 22, 2022, 05:20 PM • Last activity: Aug 25, 2023, 10:39 AM
0 votes
1 answers
1021 views
Recursively fix corrupted video files with ffmpeg
I think I'm pretty close to having a code which will start at a directory, then spit out a fixed copy, using fd (instead of find) and ffmpeg. I have written the if statement here as psudo-code: for i in $(fd -e .mp4 -e .avi); do if [ffmpeg -v error -i "$i" -f null - 2] has an error, then ffmpeg -err...
I think I'm pretty close to having a code which will start at a directory, then spit out a fixed copy, using fd (instead of find) and ffmpeg. I have written the if statement here as psudo-code: for i in $(fd -e .mp4 -e .avi); do if [ffmpeg -v error -i "$i" -f null - 2] has an error, then ffmpeg -err_detect ignore_err -i video.mkv -c copy video_fixed.mkv; done I believe that when you use 'fatal' if there is no fatal error, the file will be blank/zero. Which would be easier, but I think 'error' is more appropriate. What I want to modify is to have the IF statement execute if there are errors, and do nothing if not. If there are errors it will create the video_fixed.mkv. However, I also don't want this to be video_fixed.mkv, I want it to be the same file name as $i with the same file extension as the original, and to replace the original with it. I'm also not sure if $i is just the filename, or the filename including the entire path, which makes things tricky, I'd have to capture the string after the last '/' as the file name. If it's too hard to do the comparison, I'll have to just copy all the files regardless of if they have errors, but to do this I'll still need to name and override the copies to be the same as the originals. Thanks
1toneboy (465 rep)
Aug 9, 2023, 12:37 PM • Last activity: Aug 14, 2023, 10:05 PM
Showing page 1 of 20 total questions