Bash script not recognizing file - bash

I am attempting to write a bash script. In a test, I wrote a script to check for the existence of test.txt. However, no matter how many times I try to change the formatting, the code still does not recognize the file.
while [ "$INPUT" != "quit" ]; do
read INPUT
COMMANDFILE=test.txt
if [ -f $COMMANDFILE ]; then
echo "Found file!"
fi
done
I am 100% positive text.txt exists and is in the same folder as my script.

in this case I would add some debug lines to my script to make sure my thinking is correct. For instance:
while [ "$INPUT" != "quit" ]; do
read INPUT
COMMANDFILE=test.txt
echo "debug: now I'm in $( pwd ) directory. dir listing:"
ls -la
if [ -f $COMMANDFILE ]; then
echo "Found file!"
fi
done
also, please note that linux filenames are case sensitive (meaning you can have test.txt and TeSt.txt in the same directory). So, for instance if you have the file named TEST.TXT, [ -f test.txt ] will evaluate to false (unless test.txt exists as well)

Related

Can not locate a file in a bash script?

I am running a shell script which expects a file in a directory but I can not seem to locate it.
This is my shell script
#!/usr/bin/env bash
# expects a file to be present in current directory called INPUT_FILE
# this is the value set in the jenkins config
if [ ! -f INPUT_FILE ] ;then
echo "file ${INPUT_FILE} does not exist"
exit 1
fi
And in windows I am running a shell script from a directory like this
D:\scripts> ./all/script.sh
I tried to put INPUT_FILE.csv in scripts folder and also in all folder but it does not seem to work. Where should this file be present?
Make sure you have the correct filename.
Windows hides the extension of a file, when you look for INPUT_FILE.csv use
if [ ! -f INPUT_FILE.csv ] ;then
echo "file INPUT_FILE.csv does not exist"
exit 1
fi
You tried to use the variable INPUT_FILE. When you want this, try
input_file="INPUT_FILE.csv"
if [ ! -f "${input_file}" ]; then
echo "file ${input_file} does not exist"
exit 1
fi
Also note that bash is case sensitive, so INPUT_FILE.csv is different from input_file.csv.
It's better to list files first to verify the extension and all file names in the directory then check for the existence of the files.
#!/usr/bin/env bash
ALL_FILES=$(ls -I "*.sh") # This will list all file except .sh
echo "Files in current Directory $ALL_FILES"
INPUT_FILE="INPUT_FILE" # or INPUT_FILE="INPUT_FILE.csv"
if [ ! -f $INPUT_FILE ] ;then
echo "file ${INPUT_FILE} does not exist"
exit 1
else
echo "file exist ${INPUT_FILE}"
exit 0
fi
The first advantage, It will list all the file and the second one, If exist you will get the output.

how to check if a file exist and is a text file?

Hi everyone I need to check if a file exist with a shell script. I did some digging and ended up with this syntax but I'm not sure why it isn't working
(please bear in mind that you are talking to beginner)
I've found that you can add -e for example to check if it exist but I didn't get where these shortcuts came form or their names
#! /bin/bash
if [ "$#" = "1" ]
then
if [ -e $($1) ] && [ -f $($1) ]
then echo 'the file exists'
fi
fi
In idiomatic Bash:
#!/usr/bin/env bash
if [[ -f "${1-}" ]]
then
echo 'the file exists'
fi
Correct shebang
[[ rather than [
-f implies -e
No need for semicolons or single-use variables.
Please keep in mind that this does not tell you whether the file is a text file. The only "definition" of a text file as opposed to any other file is whether it contains only printable characters, and even that falls short of dealing with UTF BOM characters and non-ASCII character sets. For that you may want to look at the non-authoritative output of file "${1-}", for example:
$ file ~/.bashrc
/home/username/.bashrc: ASCII text
More in the Bash Guide.
#!/bin/bash
if [ "$#" == 1 ]; then
if [[ -e "$1" && -f "$1" ]]; then
echo 'The file exists';
fi
fi
You should put every conditional && between [[ ]] symbols otherwise it will be interpreted as execute if success.
#! /bin/sh
FILE=$1 # get filename from commandline
if [ -f $FILE ]; then
echo "file $FILE exists"
fi
See the fine manual page of test commands, which are built-in in the different shells: man test; man sh; man bash
You will also find many shell primers which explain this very nicely.
Or see bash reference manual: https://www.gnu.org/software/bash/manual/bash.pdf

Unix shell script to check if a file or directory with same name exists

I want to check if a file or directory with same name exists.
Is there any operator (expect -e) to check the file or directory, I dont want to add any extra condition.
Following code works fine to check the existence of a file:
#!/bin/bash
if [ -e /path/to/the/file/sample ]
then
echo "ok"
else
echo "nok"
fi
Note that sample can be a file or a directory.
In my tests with bash 4.2 , the condition [ -e /path/to/the/file/sample ] works for BOTH files and directories.
As an alternative you can :
Either to use another operator like -d according to bash man page.
if [ -e /path/to/the/file/sample ] || [ -d /path/to/the/file/sample ];then echo "ok"; else echo "nok";fi
Or to use the exit code of a command like ls.
if ls "/path/to/the/file/sample" &>/dev/null ; then echo "is here";else echo "not here";fi
If you try to perform ls on an existed file or directory ls will return 0, otherwise will return a non-zero value (returns 2 in my tests for non-existed files or directories).
Quoting is necessary to handle correct names that may include spaces.

Treating space as newline character in bash

I have written a bash just to display the name of all the files of a given directory but when I am running this it breaking the file name which has spaces.
if [ $# -eq 0 ]
then
echo "give a source directory in the command line argument in order to rename the jpg file"
exit 1
fi
if [ ! -d "$1" ]; then
exit 2
fi
if [ -d "$1" ]
then
for i in $(ls "$1")
do
echo "$i"
done
fi
I am getting the following thing when I run the bash script
21151991jatinkhurana_image
(co
py).jpg
24041991jatinkhurana_im
age.jpg
35041991jatinkhurana_image
.jpg
The thing that i have tried till now is resetting the IFS variable like IFS=$(echo -en "\t\n\0") but found no change....
If anyone know please help me.....
Do not loop through the result of ls. Parsing ls makes world worse (good read: Why you shouldn't parse the output of ls).
Instead, you can do make use of the *, that expands to the existing content in a given directory:
for file in /your/dir/*
do
echo "this is my file: $file"
done
Using variables:
for file in $dir/*
do
echo "this is my file: $file"
done

Bash script - Nested If Statement for If File Doesn't Exist

I'm trying to compile a script that will read user input, and check if the file after the y/n statement. Then it will make files executable. I think the problem with my script is conditional ordering but check it out yourself:
target=/home/user/bin/
cd $target
read -p "This will make the command executable. Are you sure? (y/n)" CONT
if [ "$CONT" == "y" ];
then
chmod +x $1
echo "File $1 is now executable."
else
if [ "$(ls -A /home/user/bin/)" ];
then
echo "File not found."
else
echo "Terminating..."
fi
fi
As I said, I need the script to scan for the file after the y/n statement is printed. The script works fine how it is but still gives the "file is now executable" even if the argument file doesn't exist (but just gives the standard system "cannot find file" message after the echo'd text).
Your script is mostly correct, you just need to check if the file exists first. Also, it's not the best practice to use cd in shell scripts and not needed here.
So re-writing it
#!/bin/bash
target="/home/user/bin/$1"
if [[ ! -f $target ]]; then
echo "File not found."
else
read -p "This will make the command executable. Are you sure? (y/n) " CONT
if [[ $CONT == "y" ]]; then
chmod +x "$target"
echo "File $1 is now executable."
else
echo "Terminating..."
fi
fi
To get an understanding:
Your script will take one argument (a name of a file).
You ask if you want to make that file executable.
If the answer is 'yes', you make the file executable.
Otherwise, you don't.
You want to verify that the file exists too?
I'm trying to understand your logic. What does this:
if [ "$(ls -A /home/user/bin/)" ];
suppose to do. The [ ... ] syntax is a test. And, it has to be one of the valid tests you see here. For example, There's a test:
-e file: True if file exists.
That mean, I can see if your file is under /home/user/bin:
target="/home/user/bin"
if [ -e "$target/$file" ] # The "-e" test for existence
then
echo "Hey! $file exists in the $target directory. I can make it executable."
else
echo "Sorry, $file is not in the $target directory. Can't touch it."
fi
Your $(ls -A /home/user/bin/) will produce a file listing. It's not a valid test like -e unless it just so happens that the first file in your listing is something like -e or -d.
Try to clarify what you want to do. I think this is something more along the lines you want:
#! /bin/bash
target="/home/user/bin"
if [ -z "$1" ] # Did the user give you a parameter
then
echo "No file name given"
exit 2
fi
# File given, see if it exists in $target directory
if [ ! -e "$target/$1" ]
then
echo "File '$target/$1' does not exist."
exit 2
fi
# File was given and exists in the $target directory
read -p"Do you want $target/$1 to be executable? (y/n)" continue
if [ "y" = "$continue" ]
then
chmod +x "$target/$1"
fi
Note how I'm using the testing, and if the testing fails, I simply exit the program. This way, I don't have to keep embedding if/then statements in if/then statements.

Resources