2

I need to write a Unix Shell script in such a way if .txt files exists in the path, it should return 0. If some other files exists it should return 1

I tried the below script but it is not working..

#!/bin/sh
cd /shz/abc_test/test/test_add/SourceFiles/test1/test01/test02/
chk_files()
{
if [ -e *.txt ]; then
      echo "File Exists" 
      return 0
      exit
else
      echo "File doesn't exists" 
      return 1
      exit
fi
return
}
Sherin Shaziya
  • 127
  • 1
  • 7
  • 2
    1) Redundant use of `return`s and `exit`s. Choose one. 2) You must call a function for it to run. Put `chk_files` just below that function and you're done. – Darkman Oct 02 '22 at 06:52
  • 2
    What @Darkman said, plus: how do you know the `cd` worked? What if there is a typo? `if !cd /to/here; then prinf "couldn't change directory\n"; exit 1; fi` – Kaz Oct 02 '22 at 07:57
  • 2
    The `-e` test doesn't work with wildcards -- it'll work by accident if there are zero or one matching files, but fail completely if there's more than one .txt file. See ["Test whether a glob has any matches in Bash"](https://stackoverflow.com/questions/2937407/test-whether-a-glob-has-any-matches-in-bash) for methods that actually work right. – Gordon Davisson Oct 02 '22 at 07:59
  • 1
    `exit` and `return` are not equivalent. `exit` causes the shell to exit. `return` returns from a _function_ (or dot script). Using them consecutively makes no sense since the one that comes later will never be executed. – M. Nejat Aydin Oct 02 '22 at 08:12
  • 2
    `bash` solution could be simply `chk_files() { compgen -G '*.txt' >/dev/null; }`, but this may not work in POSIX `sh`. – M. Nejat Aydin Oct 02 '22 at 08:26

2 Answers2

3
has_text_files()
{
  for f in ./*.txt; do
    if [ -f "$f" ]; then
      return 0
    fi
  done
  return 1
}

The above code:

  • ignores directories that are named *.txt.
  • doesn't print anything, it only returns the status.
  • is extra careful about strange filenames, such as filenames starting with - or containing spaces.
  • Has a more appropriate function name has_text_files instead of the unspecific chk_files.
Roland Illig
  • 40,703
  • 10
  • 88
  • 121
0

Of course munch more advanced script can be developed. I see you are going to use simple way. So, you script fails when multiple files are exist. I updated function part and looks it is working.

chk_files()
{
ifExist=$(ls| grep ".txt$")      # check Files are exist, but no need to list and print.
if [ $? -eq 0 ]; then   # check return code of above command is success (0)
      echo "File Exists" 
      return 0
else
      echo "File doesn't exists" 
      return 1
fi
}
aze2201
  • 453
  • 5
  • 12
  • 1
    I updated script. Now it it list files with txt endings via grep regex. – aze2201 Oct 02 '22 at 08:53
  • 1
    if you want to return just echo 0 or 1. If you want to use under some script you can use directly exit 0 or 1 as well. But I suggest use echo 0 or 1, it will be easy to maintain. – aze2201 Oct 02 '22 at 08:54
  • 1
    It's nice you provided a solution changing the code minimally. That third `return` can be quite confusing specially because it should never run too. I would create a local variable in the beginning of the loop `ret=1`, assign it to zero if the file exists and return it in the end. – Jardel Lucca Oct 02 '22 at 14:38
  • `exit` after `return` is useless – Roland Illig Oct 02 '22 at 17:10
  • exactly. That is best practice. Otherwise you can completelly remove 3 rd return. It is useful to assign status to variable and return at the then when your script is working result. i.e ls|grep file && echo FIne || echo BAD. Here is Fine or BAD based on return value of ls|grep file – aze2201 Oct 02 '22 at 22:38