1

I want to touch each file in a directory:

files=$(ls -a "node_modules/suman-types/dts")

echo "files $files";

for file in "$files"; do
    echo "touching file $file";
    touch "node_modules/suman-types/dts/$file";
done

but after running that, I get:

inject.d.ts
injection.d.ts
integrant-value-container.d.ts
it.d.ts
reporters.d.ts
runner.d.ts
suman-utils.d.ts
suman.d.ts
table-data.d.ts
test-suite-maker.d.ts
test-suite.d.ts: File name too long

What is that "File name too long" message about?

Update #1

I changed my script to this:

files=$(find "node_modules/suman-types/dts" -name "*.d.ts")

for file in "$files"; do
    echo "touching file $file";
    touch "$file";
done

touch "node_modules/suman-types"

But then I get this:

$ ./types-touch.sh
    touching file node_modules/suman-types/dts/after-each.d.ts
    node_modules/suman-types/dts/after.d.ts
    node_modules/suman-types/dts/before-each.d.ts
    node_modules/suman-types/dts/before.d.ts
    node_modules/suman-types/dts/describe.d.ts
    node_modules/suman-types/dts/global.d.ts
    node_modules/suman-types/dts/index-init.d.ts
    node_modules/suman-types/dts/inject.d.ts
    node_modules/suman-types/dts/injection.d.ts
    node_modules/suman-types/dts/integrant-value-container.d.ts
    node_modules/suman-types/dts/it.d.ts
    node_modules/suman-types/dts/reporters.d.ts
    node_modules/suman-types/dts/runner.d.ts
    node_modules/suman-types/dts/suman-utils.d.ts
    node_modules/suman-types/dts/suman.d.ts
    node_modules/suman-types/dts/table-data.d.ts
    node_modules/suman-types/dts/test-suite-maker.d.ts
    node_modules/suman-types/dts/test-suite.d.ts
    touch: node_modules/suman-types/dts/after-each.d.ts
    node_modules/suman-types/dts/after.d.ts
    node_modules/suman-types/dts/before-each.d.ts
    node_modules/suman-types/dts/before.d.ts
    node_modules/suman-types/dts/describe.d.ts
    node_modules/suman-types/dts/global.d.ts
    node_modules/suman-types/dts/index-init.d.ts
    node_modules/suman-types/dts/inject.d.ts
    node_modules/suman-types/dts/injection.d.ts
    node_modules/suman-types/dts/integrant-value-container.d.ts
    node_modules/suman-types/dts/it.d.ts
    node_modules/suman-types/dts/reporters.d.ts
    node_modules/suman-types/dts/runner.d.ts
    node_modules/suman-types/dts/suman-utils.d.ts
    node_modules/suman-types/dts/suman.d.ts
    node_modules/suman-types/dts/table-data.d.ts
    node_modules/suman-types/dts/test-suite-maker.d.ts
    node_modules/suman-types/dts/test-suite.d.ts: No such file or directory
slm
  • 369,824

2 Answers2

10

Your problem stems from capturing all of the ls output into a single (string) variable named files. The variable looks something like:

filename1\nfilename2\nfilename3\n...

See for yourself with:

echo "$files" | od -c

What you're really doing is looping once over a really long string that corresponds to a file that doesn't exist. The error you got was slightly informative -- it's telling you that this long string-of-a-filename doesn't exist.

To touch every file in a directory, just use shell globbing and run touch (the glob would only take files in that one directory):

touch node_modules/suman-types/dts/*

or touch them one by one:

for file in node_modules/suman-types/dts/*; do touch "$file"; done

or use find to find all files recursively within the directory, and have it run touch on them:

find node_modules/suman-types/dts -type f -exec touch -- {} \;

or in shells that support it (Bash/ksh/zsh, with some variations), use the recursive glob operator **:

shopt -s globstar # in Bash
for file in node_modules/suman-types/dts/**/*; do
    touch "$file"
done
ilkkachu
  • 138,973
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
2

Try doing it with filename expansion:

for file in node_modules/suman-types/dts/*; do
  echo "Touching file: ${file##*/}"
  touch "${file}"
done
nxnev
  • 3,654