Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perl -pi -e s:foo:foo2: FILE mishandles symlinks? #6785

Open
p5pRT opened this issue Sep 23, 2003 · 11 comments
Open

perl -pi -e s:foo:foo2: FILE mishandles symlinks? #6785

p5pRT opened this issue Sep 23, 2003 · 11 comments

Comments

@p5pRT
Copy link

p5pRT commented Sep 23, 2003

Migrated from rt.perl.org#24000 (status was 'open')

Searchable as RT24000$

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2003

From pekkas@netcore.fi

Hi,

On Red Hat Linux 7.3 and 9 (perl 5.6.1 and 5.8, respectively), at least,
perl seems to be *seriously* mishandling symlinks with structures like
"perl -pi -e s​:foo​:foo2​: FILE". If FILE is a symlink, perl doesn't follow
it, causing a symlink being converted to a file in the directory where the
symlink resided in.

Smells very much like a bug..?

The behaviour should be apparent from below​:

pekkas​: /home/pekkas/perl$ echo test > unf2
pekkas​: /home/pekkas/perl$ ln -s unf2 unf
pekkas​: /home/pekkas/perl$ ls -la unf*
lrwxrwxrwx 1 pekkas pekkas 4 Sep 23 14​:15 unf -> unf2
-rw-rw-r-- 1 pekkas pekkas 5 Sep 23 14​:14 unf2
pekkas​: /home/pekkas/perl$ perl -pi -e s​:test​:testx​: unf
pekkas​: /home/pekkas/perl$ ls -la unf*
-rw-rw-r-- 1 pekkas pekkas 6 Sep 23 14​:15 unf
-rw-rw-r-- 1 pekkas pekkas 5 Sep 23 14​:14 unf2
pekkas​: /home/pekkas/perl$ more unf*
:​::​::​::​::​::​::​:
unf
:​::​::​::​::​::​::​:
testx
:​::​::​::​::​::​::​:
unf2
:​::​::​::​::​::​::​:
test

--
Pekka Savola "You each name yourselves king, yet the
Netcore Oy kingdom bleeds."
Systems. Networks. Security. -- George R.R. Martin​: A Clash of Kings

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2003

From @rgarcia

Pekka Savola (via RT) wrote​:

On Red Hat Linux 7.3 and 9 (perl 5.6.1 and 5.8, respectively), at least,
perl seems to be *seriously* mishandling symlinks with structures like
"perl -pi -e s​:foo​:foo2​: FILE". If FILE is a symlink, perl doesn't follow
it, causing a symlink being converted to a file in the directory where the
symlink resided in.

At first sight, I don't think perl should transparently follow symlinks.
That's not what I expect it to do. However this can be argued.

Note that you can force perl to follow symlinks by inserting at the top
of your script :

  BEGIN { @​ARGV = map { -l $_ ? readlink : $_ } @​ARGV; }

[You could even put this in a FollowSymlinks.pm file, to be loaded via
"PERL5OPT=-IFollowSymlinks".]

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2003

From pekkas@netcore.fi

On 23 Sep 2003, Rafael Garcia-Suarez wrote​:

Pekka Savola (via RT) wrote​:

On Red Hat Linux 7.3 and 9 (perl 5.6.1 and 5.8, respectively), at least,
perl seems to be *seriously* mishandling symlinks with structures like
"perl -pi -e s​:foo​:foo2​: FILE". If FILE is a symlink, perl doesn't follow
it, causing a symlink being converted to a file in the directory where the
symlink resided in.

At first sight, I don't think perl should transparently follow symlinks.
That's not what I expect it to do. However this can be argued.

I have to really, really disagree with you here. Consider what the script
is supposed to be doing​: "replace test with textx in the file". How is
this different e.g. from firing up *any* text editor and making that
replacement? When I make operations on the symlink, I certainly _expect_
them to be done at the file the symlink points to. This perl behaviour
breaks the principle of least surprise badly, IMHO.

Note that you can force perl to follow symlinks by inserting at the top
of your script :

BEGIN \{ @​ARGV = map \{ \-l $\_ ? readlink : $\_ \} @​ARGV; \}

[You could even put this in a FollowSymlinks.pm file, to be loaded via
"PERL5OPT=-IFollowSymlinks".]

.. right but this is really a bit too complex, and won't help those whose
expectations are broken by current behaviour. However, I could imagine
that a perl command-line argument could be possible, even though not
really the optimal way to solve the problem.

--
Pekka Savola "You each name yourselves king, yet the
Netcore Oy kingdom bleeds."
Systems. Networks. Security. -- George R.R. Martin​: A Clash of Kings

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2003

From @ysth

On Tue, Sep 23, 2003 at 03​:23​:46PM +0200, Rafael Garcia-Suarez <raphel.garcia-suarez@​hexaflux.com> wrote​:

Pekka Savola (via RT) wrote​:

On Red Hat Linux 7.3 and 9 (perl 5.6.1 and 5.8, respectively), at least,
perl seems to be *seriously* mishandling symlinks with structures like
"perl -pi -e s​:foo​:foo2​: FILE". If FILE is a symlink, perl doesn't follow
it, causing a symlink being converted to a file in the directory where the
symlink resided in.

At first sight, I don't think perl should transparently follow symlinks.
That's not what I expect it to do. However this can be argued.

Perhaps at least a warning for -i on a symlink?

Note that you can force perl to follow symlinks by inserting at the top
of your script :

BEGIN \{ @&#8203;ARGV = map \{ \-l $\_ ? readlink : $\_ \} @&#8203;ARGV; \}

Needs to recurse if readlink returns a symlink.

@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2003

From Robin.Barker@npl.co.uk

Needs to recurse if readlink returns a symlink.
And to resolve the output of readlink relative to the link's
directory (unless readlink returns an absolute filename).

Robin

-----Original Message-----
From​: Yitzchak Scott-Thoennes [mailto​:sthoenna@​efn.org]
Sent​: 23 September 2003 18​:04
To​: Rafael Garcia-Suarez
Cc​: perl5-porters@​perl.org
Subject​: Re​: [perl #24000] perl -pi -e s​:foo​:foo2​: FILE mishandles
symlinks?

On Tue, Sep 23, 2003 at 03​:23​:46PM +0200, Rafael Garcia-Suarez
<raphel.garcia-suarez@​hexaflux.com> wrote​:

Pekka Savola (via RT) wrote​:

On Red Hat Linux 7.3 and 9 (perl 5.6.1 and 5.8, respectively), at
least,
perl seems to be *seriously* mishandling symlinks with structures
like
"perl -pi -e s​:foo​:foo2​: FILE". If FILE is a symlink, perl doesn't
follow
it, causing a symlink being converted to a file in the directory
where the
symlink resided in.

At first sight, I don't think perl should transparently follow
symlinks.
That's not what I expect it to do. However this can be argued.

Perhaps at least a warning for -i on a symlink?

Note that you can force perl to follow symlinks by inserting at the
top
of your script :

BEGIN \{ @&#8203;ARGV = map \{ \-l $\_ ? readlink : $\_ \} @&#8203;ARGV; \}

Needs to recurse if readlink returns a symlink.


This e-mail and any attachments may contain confidential and/or
privileged material; it is for the intended addressee(s) only.
If you are not a named addressee, you must not use, retain or
disclose such information.

NPL Management Ltd cannot guarantee that the e-mail or any
attachments are free from viruses.

NPL Management Ltd. Registered in England and Wales. No​: 2937881
Registered Office​: Teddington, Middlesex, United Kingdom TW11 0LW.


@p5pRT
Copy link
Author

p5pRT commented Sep 23, 2003

From ajs@ajs.com

On Tue, 2003-09-23 at 13​:08, Robin Barker wrote​:

Needs to recurse if readlink returns a symlink.
And to resolve the output of readlink relative to the link's
directory (unless readlink returns an absolute filename).

No, that way lies dragons. Perl should have some switch that at the
C-level causes the change from current behavior in doio.c (around like
811 in 5.8.0)​:

* Rename old name to new name
* Open STDOUT filehandle on old name for create/writing
* Open ARGV filehandle on new name for reading

to the more complex​:

* Copy old file to new name
* Replicate ownership and permissions from old file to new file (if
possible)
* Open STDOUT filehandle on old name for create/truncate/writing
* Open ARGV filehandle on new name for reading

There are sound technical reasons to do either one, but I *would* argue
that the average joe on the street expects the second one by default....

--
Aaron Sherman <ajs@​ajs.com>
Senior Systems Engineer and Toolsmith
"It's the sound of a satellite saying, 'get me down!'" -Shriekback

@p5pRT
Copy link
Author

p5pRT commented Sep 28, 2012

From @jkeenan

On Tue Sep 23 09​:39​:38 2003, pekkas@​netcore.fi wrote​:

On 23 Sep 2003, Rafael Garcia-Suarez wrote​:

Pekka Savola (via RT) wrote​:

On Red Hat Linux 7.3 and 9 (perl 5.6.1 and 5.8, respectively), at
least,
perl seems to be *seriously* mishandling symlinks with structures
like
"perl -pi -e s​:foo​:foo2​: FILE". If FILE is a symlink, perl
doesn't follow
it, causing a symlink being converted to a file in the directory
where the
symlink resided in.

At first sight, I don't think perl should transparently follow
symlinks.
That's not what I expect it to do. However this can be argued.

I have to really, really disagree with you here. Consider what the
script
is supposed to be doing​: "replace test with textx in the file". How
is
this different e.g. from firing up *any* text editor and making that
replacement? When I make operations on the symlink, I certainly
_expect_
them to be done at the file the symlink points to. This perl
behaviour
breaks the principle of least surprise badly, IMHO.

Note that you can force perl to follow symlinks by inserting at the
top
of your script :

BEGIN \{ @&#8203;ARGV = map \{ \-l $\_ ? readlink : $\_ \} @&#8203;ARGV; \}

[You could even put this in a FollowSymlinks.pm file, to be loaded
via
"PERL5OPT=-IFollowSymlinks".]

.. right but this is really a bit too complex, and won't help those
whose
expectations are broken by current behaviour. However, I could
imagine
that a perl command-line argument could be possible, even though not
really the optimal way to solve the problem.

This ticket has not attracted comments in about nine years. From
skimming the discussion, my impression is that Rafael thought no change
in Perl's then current behavior was necessary -- but the OP wasn't
satisfied with that.

Could someone give this ticket some attention and make a recommendation?

Thank you very much.
Jim Keenan

@p5pRT
Copy link
Author

p5pRT commented Jul 5, 2016

From @dcollinsn

Confirmed in blead.

I definitely thing this is a bug that needs to be repaired. At minimum, as suggested, I think a warning would be helpful when the target file is a symlink that is not being followed. After all, this is "like sed", as perl -h says. If you're following the link to read the file, you should also follow the link to write it.

@p5pRT
Copy link
Author

p5pRT commented Jul 5, 2016

From @tonycoz

On Tue Jul 05 15​:47​:08 2016, dcollinsn@​gmail.com wrote​:

Confirmed in blead.

I definitely thing this is a bug that needs to be repaired. At
minimum, as suggested, I think a warning would be helpful when the
target file is a symlink that is not being followed. After all, this
is "like sed", as perl -h says. If you're following the link to read
the file, you should also follow the link to write it.

According to its documentation, the default for GNU sed is to break the
symlink​:

`--follow-symlinks'
  This option is available only on platforms that support symbolic
  links and has an effect only if option `-i' is specified. In this
  case, if the file that is specified on the command line is a
  symbolic link, `sed' will follow the link and edit the ultimate
  destination of the link. The default behavior is to break the
  symbolic link, so that the link destination will not be modified.

which is the behaviour I expected.

(POSIX, BSD, Solaris sed don't seem to support in-place editing.)

My work in progress in-place edit branch doesn't attempt to follow symlinks.

Tony

@p5pRT
Copy link
Author

p5pRT commented Jul 6, 2016

From @dcollinsn

Well then, I suppose it is just my expectations that are defective. ;) Is
there a place to document this better, or should we just mark this rejected?

On Tue, Jul 5, 2016 at 7​:50 PM, Tony Cook via RT <perlbug-followup@​perl.org>
wrote​:

On Tue Jul 05 15​:47​:08 2016, dcollinsn@​gmail.com wrote​:

Confirmed in blead.

I definitely thing this is a bug that needs to be repaired. At
minimum, as suggested, I think a warning would be helpful when the
target file is a symlink that is not being followed. After all, this
is "like sed", as perl -h says. If you're following the link to read
the file, you should also follow the link to write it.

According to its documentation, the default for GNU sed is to break the
symlink​:

`--follow-symlinks'
This option is available only on platforms that support symbolic
links and has an effect only if option `-i' is specified. In this
case, if the file that is specified on the command line is a
symbolic link, `sed' will follow the link and edit the ultimate
destination of the link. The default behavior is to break the
symbolic link, so that the link destination will not be modified.

which is the behaviour I expected.

(POSIX, BSD, Solaris sed don't seem to support in-place editing.)

My work in progress in-place edit branch doesn't attempt to follow
symlinks.

Tony

---
via perlbug​: queue​: perl5 status​: open
https://rt-archive.perl.org/perl5/Ticket/Display.html?id=24000

@p5pRT
Copy link
Author

p5pRT commented Jul 6, 2016

From @tonycoz

On Tue, Jul 05, 2016 at 08​:14​:11PM -0400, Dan Collins wrote​:

Well then, I suppose it is just my expectations that are defective. ;) Is
there a place to document this better, or should we just mark this rejected?

From the -i documentation​:

Note that because B<-i> renames or deletes the original file before
creating a new file of the same name, Unix-style soft and hard links will
not be preserved.

which might be re-worded or expanded on.

Tony

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants