I am able to do this in shell command line.

filename="/home/vikrant_singh_rana/testing/110001_ABC Traffic_04May2020_header_only.csv"
output_filename=$(basename "$filename")

cat "/home/vikrant_singh_rana/testing/110001_ABC Traffic_04May2020_header_only.csv" > /home/vikrant_singh_rana/enrichment_files/"$output_filename"

It was able to read given file from '/home/vikrant_singh_rana/testing' and has written file with same name to other dir '/home/vikrant_singh_rana/enrichment_files'

When I am doing same thing in shell script. Its not working


# Go to where the files are located
#reading file from directory
for filename in $filedir; do
        #echo $filename
        output_filename=$(basename "$filename")
        #echo $output_filename

done > /home/vikrant_singh_rana/enrichment_files/"$output_filename"

while running this I am getting this error

/home/vikrant_singh_rana/enrichment_files/: Is a directory
  • You're using "$output_filename" outside the loop, but it's first set inside the loop. (Think of what you're running as { for fileiname in ... do ...; done; } > /home/vikrant_singh_rana/enrichment_files/"$output_filename" What would the point even be, since the variable changes inside the loop each time, but you're only redirecting once?
    – muru
    Jun 9, 2020 at 3:23
  • Why do you use cat for copying files...? Jun 9, 2020 at 3:25
  • that I just did for checking the command.. may be I need to use a cp or move statement inside a loop itself Jun 9, 2020 at 3:27
  • 1
    @alecxs That is not correct. cp uses the existing inode. Even cp -p does; it just changes the metadata. sed -i is something completely different because it creates a temporary file and renames that in the end, i.e. replaces the old inode with the new one. Jun 11, 2020 at 9:54
  • 1
    @HaukeLaging thx for clarifying, seems i have mixed up things regarding inodes. i just remember i have had problems with cp doesn't work for secontext (even busybox cp with -c flag did not work on debian) so i ended up with cat
    – alecxs
    Jun 11, 2020 at 10:02

1 Answer 1


You use pathname expansion (*) incorrectly. And as muru's comment states you mix the use of variables inside and outside the loop.

#! /bin/bash

cd "$source_dir_path" || exit 1
for filename in *; do
    test -f "$target_path" && { echo "File '${filename}' exists; skipping"; continue; }
    cp -p "$filename" "$target_path"
  • actually I was reading file from dir and was doing something on it and trying to write that new file with same name to other directory Jun 9, 2020 at 4:10
  • @vikrantrana Then you just have to exchange the cp line against the required command. Jun 9, 2020 at 4:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .