1

I'm trying to make a soft link inside a directory with a Perl script.

I can use ln to create a link to /home/apuntes inside the directory /home/scripts like this:

ln -s /home/apuntes /home/scripts

But I don't know how to do this with Perl. I tried

symlink("home/apuntes", "home/scripts");

but it didn't create the link and there are no errors. Can anyone help me?

ThisSuitIsBlackNot
  • 23,492
  • 9
  • 63
  • 110
Ghafit
  • 51
  • 1
  • 6
  • PD: I can not use system calls – Ghafit Jun 15 '16 at 20:58
  • 1
    `symlink("home/apuntes", "home/scripts")` is different from the shell command `ln -s /home/apuntes /home/scripts` because your symlink call doesn't have a leading forward slash. Is that your problem? – mob Jun 15 '16 at 21:03
  • 1
    Also check `$!` for errors if you're not already doing that. – mob Jun 15 '16 at 21:03
  • I'm cheking and It throws: The file already exits. – Ghafit Jun 15 '16 at 21:12
  • 1
    $! is only meaningful after an error; if symlink is returning 1 it isn't – ysth Jun 15 '16 at 21:39
  • Hi Ghafit, when I first read your question, I didn't realize you wanted to create a link *inside* `/home/scripts`, which is what your answer does. I edited your question to make this more clear, please edit again or rollback my edit if I misinterpreted you. – ThisSuitIsBlackNot Jun 16 '16 at 01:41

4 Answers4

4

Perl's symlink doesn't support passing a directory instead of a link name the way you can with ln. You have to pass the link name:

symlink('/home/apuntes', '/home/scripts/softlinkname');
ThisSuitIsBlackNot
  • 23,492
  • 9
  • 63
  • 110
Ghafit
  • 51
  • 1
  • 6
  • @ThisSuitIsBlackNot this is a discrepancy between ln and perl's symlink; ln has a `ln TARGET DIRECTORY` form as well as the `ln TARGET LINK_NAME` form, but symlink only has the latter. so this is a good answer, but the question was lacking the details of what was actually wanted (and where the OP said symlink was returning 1 they were presumably mistaken) – ysth Jun 15 '16 at 23:07
2

Did you try symlink('/home/apuntes', '/home/scripts')? (Your question mentions it without the / before home.) It should work, returning 1 on success and 0 (and setting $!) on failure.

But normally only root would have write access to /home; are you running it as root?

This works fine for me:

sudo perl -wE'say symlink("/home/ysth","/home/xysth") || "Error: $!"'

printing 1 the first time and "Error: File exists" the second time.

Running sudo strace perl -wE'say symlink("/home/ysth","/home/xysth") || "Error: $!"' gives (after a lot of other stuff):

symlink("/home/ysth", "/home/xysth")    = 0
write(1, "1\n", 21
)                      = 2

and running a second time gives:

symlink("/home/ysth", "/home/xysth")    = -1 EEXIST (File exists)
write(1, "Error: File exists\n", 19Error: File exists
)    = 19

What happens when you try?

ysth
  • 96,171
  • 6
  • 121
  • 214
  • Yes, I'm running it as root and I have also tryed symlink('/home/apuntes', '/home/scripts') It returns 1, and does not create the softlink – Ghafit Jun 15 '16 at 21:10
  • What OS is this? Maybe try running it under strace and see if that tells you anything? – ysth Jun 15 '16 at 21:36
  • updated answer. and are you certain you have the parameters in the correct order (existing file first, new symlink name second)? – ysth Jun 15 '16 at 21:46
0

I was facing similar problem recently, but then it turned out that I had a leading whitespace in the argument I was passing in the method to my method which was calling the symlink with the same arguments. Check out for these small details. I'm sure it would work!

Harshit
  • 1
  • 2
-1

What about

system(" ln -s /home/apuntes /home/scripts");

d1sr3
  • 9
  • 3