4

I have a bash command, get-modified-perl-files, that returns all the Perl files I have modified in my repository. I would like to use perltidy on all of these files.

I created a bash function to do the job:

tidy() {
    for f in `get-modified-perl-files`
    do
        echo $f
        perltidy -b $f
    done
}

According to the help page of perltidy, the -b option should create a backup of my original file and modify it in-place:

-b backup original to .bak and modify file in-place

However, when I launch my bash function, no backup is created. My files are not modified, but the output of perltidy is printed on the standard output. As a consequence, I decided to change my call to perltidy that way:

\cp $f $f.bak
perltidy $f > $f

Now, when I run my command, the backup of my file is correctly done, but the original file is emptied, and the following message is displayed:

skipping file: file.pl: Zero size

I've found a workaround which gives the result I want, but it seems far-fetched:

\cp -f $f $f.bak
echo "$(perltidy $f)" > $f

Why the -b option doesn't work? Is there a way to do the same job without using this weird redirection?


EDIT: Here is my .perltidyrc file:

--perl-best-practices
--no-standard-error-output
--closing-side-comments
--closing-side-comment-interval=10
--blanks-before-subs
--blanks-before-blocks
--maximum-line-length=130
brian d foy
  • 121,466
  • 31
  • 192
  • 551
Pierre
  • 1,647
  • 2
  • 20
  • 33
  • This is an exact duplicate of [this question](https://stackoverflow.com/questions/54229423/perltidy-always-prints-to-standard-out) – ikegami Mar 06 '21 at 03:21

2 Answers2

5

By default perltidy does not print the file contents to STDOUT. To do so requires the -st option (or --standard-output). Since you are not using this option on the perltidy command line, there is likely a .perltidyrc file with -st in it that is being used.

To ignore the .perltidyrc file, use the -npro (--noprofile) option:

perltidy -npro -b $f 

Refer to the "Using a .perltidyrc command file" section of the man page for your installed version:

perldoc perltidy

For addition debug information, you can run:

perltidy -dpro
perltidy -dop

Another possibility is that you aliased the perltidy command to perltidy -st. You should be able to avoid an alias with:

\perltidy -npro -b $f 

Now that you edited your Question to show your .perltidyrc file, it looks like the culprit is:

--perl-best-practices

Either change the rc file, or ignore it as above.

See also Perltidy always prints to standard out

toolic
  • 46,418
  • 10
  • 64
  • 104
5

perltidy $f > $f

This will never do what you want, with any program. When you run a program with > $f, that tells the shell that you want the program to run with its stdout connected to $f. So before the program is run, the shell opens $f for writing, which destroys the contents of the file. Then it connects the handle to stdout in the child, then it runs perltidy, which tries to read $f and finds... nothing, because the original contents were already wiped out. Not a recipe for success. This is why perltidy has its own "in-place editing" feature in the first place.

hobbs
  • 187,508
  • 16
  • 182
  • 271
  • 2
    The `sponge` utility is useful for utilities that don't provide in-place editing. `prog file >file` can be solved using `prog file | sponge file` – ikegami Mar 04 '21 at 18:49