I am working on a script which will create an Hard link to OneDrive with an UI option to choose folder(from the User Profile) to sync with OneDrive.
This the perl command that i am using to create Hard link in Mac:
So far I am not successful in doing this and seeing the below error:
Please suggest!!
on run
--Get the folder
set theFolder to (path to home folder) as text
--Get the path to de destination folder of the files
set destination_folder to (((path to home folder) as text) & "OneDrive - Company Systems Inc") as alias
--Generate the list of files inside theFolder
tell application "Finder"
set theItems to items of folder theFolder
set theNames to {}
repeat with anItem in theItems
set end of theNames to name of anItem
end repeat
end tell
--Let user select the files of the list
choose from list theNames with prompt "Pick the items you want to copy from:" & return & theFolder OK button name "Copy" cancel button name "Quit" with multiple selections allowed
tell result
if it is false then error number -128 -- cancel
set theChoices to it
end tell
if (count of theChoices) is greater than or equal to 1 then
repeat with aChoice in theChoices
set thisItem to (theFolder & aChoice) as alias
-- do something with thisItem
do shell script "perl -e 'link " & thisItem & ", " & destination_folder & " /Music '"
end repeat
end if
end run
You are passing aliases to your do shell script command.
This one can’t work with this class of objects.
You must coerce them as POSIX path.
As at least one of the passed pathnames contain space characters, I added the “quoted form” action so that your path would be treated correctly.
on run
--Get the folder
set theFolder to (path to home folder) as text
--Get the path to de destination folder of the files
set destination_folder to quoted form of POSIX path of (((path to home folder) as text) & "OneDrive - Company Systems Inc") # EDITED so that do shell script will be happy
--Generate the list of files inside theFolder
tell application "Finder"
set theItems to items of folder theFolder
set theNames to {}
repeat with anItem in theItems
set end of theNames to name of anItem
end repeat
end tell
--Let user select the files of the list
choose from list theNames with prompt "Pick the items you want to copy from:" & return & theFolder OK button name "Copy" cancel button name "Quit" with multiple selections allowed
tell result
if it is false then error number -128 -- cancel
set theChoices to it
end tell
if (count of theChoices) is greater than or equal to 1 then
repeat with aChoice in theChoices
set thisItem to quoted form of POSIX path of (theFolder & aChoice) # EDITED so that do shell script will be happy
-- do something with thisItem
do shell script "perl -e 'link " & thisItem & ", " & destination_folder & " /Music '"
end repeat
end if
end run
Tried with the changed one, but still seeing some other error while running the script:
From the “user selection list(folder slection)” I am just selecting “Music” from the list to get it Hardlinked to OneDrive as an testing, thats why I am including “Music” folder name after the “destination_folder” in the below command. Not sure how to handle when multiple folders are selected.
I apologize but I’m not at ease with do shell script.
I was able to generate hardlinks with :
In the script below I use two do shell script instructions to create hardlinks but I don’t like them because they can’t create hardlinks to folders
My preferred scheme is the one using ASObjC.
use AppleScript version "2.3.1"
use framework "Foundation"
use scripting additions
# two handlers borrowed from Shane STANLEY's FileManagerLib.scptd
on createHardLinkInFolder:folderPath linkedTo:originalFileOrPath
set folderPathURL to my makeURLFromFileOrPath:folderPath
set originalURL to my makeURLFromFileOrPath:originalFileOrPath
set linkName to originalURL's |lastPathComponent|()
set theLinkURL to folderPathURL's URLByAppendingPathComponent:linkName
set theFileManager to current application's NSFileManager's |defaultManager|()
set {theResult, theError} to theFileManager's linkItemAtURL:originalURL toURL:theLinkURL |error|:(reference)
if not (theResult as boolean) then error (theError's |localizedDescription|() as text)
end createHardLinkInFolder:linkedTo:
-- This handler is called by other handlers
on makeURLFromFileOrPath:theFileOrPathInput
-- make it into a Cocoa object for easier comparison
set theFileOrPath to item 1 of (current application's NSArray's arrayWithObject:theFileOrPathInput)
if (theFileOrPath's isKindOfClass:(current application's NSString)) as boolean then
if (theFileOrPath's hasPrefix:"/") as boolean then -- full POSIX path
return current application's class "NSURL"'s fileURLWithPath:theFileOrPath
else if (theFileOrPath's hasPrefix:"~") as boolean then -- POSIX path needing ~ expansion
return current application's class "NSURL"'s fileURLWithPath:(theFileOrPath's |stringByExpandingTildeInPath|())
else -- must be HFS path
return current application's class "NSURL"'s fileURLWithPath:(POSIX path of theFileOrPathInput)
end if
else if (theFileOrPath's isKindOfClass:(current application's class "NSURL")) as boolean then -- happens with files and aliases in 10.11
return theFileOrPath
else -- must be a file or alias
return current application's class "NSURL"'s fileURLWithPath:(POSIX path of theFileOrPathInput)
end if
end makeURLFromFileOrPath:
set destFolder to POSIX path of (path to desktop)
set originalItem to POSIX path of (path to scripts folder from user domain as text)
my createHardLinkInFolder:destFolder linkedTo:originalItem
set originalItem2 to POSIX path of ((path to scripts folder from user domain as text) & "Delete Diagnostics.scpt")
do shell script "ln " & quoted form of originalItem2 & " " & quoted form of destFolder
set originalItem3 to POSIX path of ((path to scripts folder from user domain as text) & "unhide all.scpt")
do shell script "link " & quoted form of originalItem3 & " " & quoted form of destFolder
I’m sorry, I don’t have time at the moment to combine bits here with your script to make it work with hard links. But I already had an Applescript that makes symlinks, and thought it might be handy for you to reference. Will get back to this later and contribute more if I can find time.
on connect_scripting_additions()
--The script makes a symlink to the dropbox shared "Scripting Additions" folder named "Scripting Additions" in the user library folder
set userPath to the POSIX path of (path to home folder)
set libraryLinkPath to userPath & "Library/Script Libraries" -- path for symlink
set dropboxPath to userPath & "Dropbox/Clipart Project/Scripts/Script Libraries" -- path for the shared dropbox folder
try
set testDropboxPath to POSIX file dropboxPath as alias
on error
display dialog "Could not find the shared Dropbox Script Libraries folder at " & dropboxPath & "." & return & "Check that you're connected to the shared \"Scripts\" folder." buttons {"Darn"} default button "Darn"
end try
set conflictChoice to ""
try
set testLibraryPath to POSIX file libraryLinkPath as alias
set conflictChoice to the button returned of (display dialog "An existing \"Script Libraries\" folder was found in your User Library. This needs to be replaced with a link to the shared Dropbox Copy." buttons {"Stop", "Delete Existing Library", "Move Existing Library to Desktop"} default button "Delete Existing Library")
end try
tell application "Finder"
if conflictChoice is "Delete Existing Library" then
do shell script "rm -r " & quoted form of libraryLinkPath
else if conflictChoice is "Move Existing Library to Desktop" then
do shell script "mv " & quoted form of libraryLinkPath & " '/Volumes/Hackintosh HD/Users/tspoon/Desktop/'"
else if conflictChoice is "Stop" then
return
end if
end tell
"/Volumes/Hackintosh HD/Users/tspoon/Desktop"
do shell script "ln -s " & quoted form of dropboxPath & " " & quoted form of libraryLinkPath
delay 0.1
try
run script "
use scripting additions
tell script \"ROT Additions\" to check_this_scripting_addition()
"
on error
display dialog "Something seems to have gone wrong with the link."
end try
end connect_scripting_additions
Are you sure that what you posted as a valid terminal command :
[format]/usr/bin/perl -e ‘link “/Users/kumar/Music”, “/Users/kumar/OneDrive - Company Systems Inc/Music”’[/format]
really do its duty.
When I run a similar one here:
[format]/usr/bin/perl -e ‘link “/Users/yvankoenig/Library/Scripts/Maybe.scpt”, “/Users/yvankoenig/Desktop/”’[/format]
it issue no error but there is no hardlink created in the desktop folder.
With this added info I was able to write the code required to use the perl command in a do shell script instruction.
# hardlink to a file
set fileName to "May be.scpt"
set linkPath to POSIX path of ((path to desktop as text) & fileName)
set originalItem to POSIX path of ((path to scripts folder from user domain as text) & fileName)
do shell script "/usr/bin/perl -e " & quoted form of ("link " & quote & originalItem & quote & ", " & quote & linkPath & quote)
# Now hardlink to a folder
set linkPath to POSIX path of ((path to desktop as text) & "Scripts")
set originalItem to POSIX path of (path to scripts folder from user domain as text)
do shell script "/usr/bin/perl -e " & quoted form of ("link " & quote & originalItem & quote & ", " & quote & linkPath & quote)
It’s execution is awfully longer than the scheme using ASObjC.
I carefully wrote that ln or link doesn’t apply to create a link to a folder.
It’s why I use ASObjC code.
For the perl code, I was just trying to respond to the original question (and its added explanations) which was explicitly upon perl, probably because the hardlink was pointing upon a folder.
This is my destination path variable, here is the actual destiny path: “/Users/kumar/OneDrive -Systems Inc/”
Here I am trying to set new destination path by adding the Users selected choice… to the end of destination path (when any folder from User Profile is selected) in this example I have selected “Music” folder.
when I am trying to echo result of variable newdestiny I am seeing the destination result path as:
Any idea how can I remove the single quotes after the OneDrive - System Systems Inc path? this is making the script to fail.
If I am just running my command without any defined variable… it works fins and creates Hard link without any error:
set destination_folder to POSIX path of (((path to home folder) as text) & "OneDrive - Systems Inc")
set newdestiny to quoted form of (destination_folder & "/Music")
set destination_folder to quoted form of destination_folder
Thanks Yvan, your trick worked for me in adding additional path to the variable and in removing the quotes.
when I am trying the to implement directory hardlinks using the command line utility provided in this link: https://github.com/selkhateeb/hardlink it works fine when implemented on the below script:
But i am still seeing the below error while implementing the Hard link using perl:
Also tried with your provided code :
Command will look like this… following the above one:
While running the above code I am seeing this error:
set theFolder to quoted form of POSIX path of (((path to home folder) as text) & "Music")
-- do shell script "echo " & theFolder & ""
set destination_folder to POSIX path of (((path to home folder) as text) & "OneDrive - Systems Inc")
set newdestiny to quoted form of (destination_folder & "/Music")
-- do shell script "echo " & newdestiny & ""
-- Hard link with hln utility works fine:
-- do shell script "/usr/local/bin/hln " & theFolder & " " & newdestiny & " "
--Hard link with perl command is failing:
do shell script "/usr/bin/perl -e 'link \"" & theFolder & "\", \"" & newdestiny & "\" '"
I can’t help you more than saying : move back to message #8 and read it carefully.
What you posted doesn’t match what I wrote in the referenced message.
Maybe added comments would help:
# hardlink to a file
set fileName to "May be.scpt"
set linkPath to POSIX path of ((path to desktop as text) & fileName) # NOT QUOTED !
set originalItem to POSIX path of ((path to scripts folder from user domain as text) & fileName) # NOT QUOTED !
do shell script "/usr/bin/perl -e " & quoted form of ("link " & quote & originalItem & quote & ", " & quote & linkPath & quote)
# Now hardlink to a folder
set linkPath to POSIX path of ((path to desktop as text) & "Scripts") # NOT QUOTED !
set originalItem to POSIX path of (path to scripts folder from user domain as text) # NOT QUOTED !
do shell script "/usr/bin/perl -e " & quoted form of ("link " & quote & originalItem & quote & ", " & quote & linkPath & quote)
# Your code :
set theFolder to quoted form of POSIX path of (((path to home folder) as text) & "Music")
set destination_folder to POSIX path of (((path to home folder) as text) & "OneDrive - Systems Inc")
set newdestiny to quoted form of (destination_folder & "/Music")
"'link \"" & theFolder & "\", \"" & newdestiny & "\" '"
--> "'link "'/Users/yvankoenig/Music'", "'/Users/yvankoenig/OneDrive - Systems Inc/Music'" '"
# What I posted :
set theFolder to POSIX path of (((path to home folder) as text) & "Music") # NOT QUOTED
set destination_folder to POSIX path of (((path to home folder) as text) & "OneDrive - Systems Inc")
set newdestiny to (destination_folder & "/Music") # NOT QUOTED
"'link \"" & theFolder & "\", \"" & newdestiny & "\" '"
--> "'link "/Users/yvankoenig/Music", "/Users/yvankoenig/OneDrive - Systems Inc/Music" '"
Of course I dropped the beginning of the instructions because your folders don’t exist on my machine !
I hope that you will see the differences between both codes.
Thanks you Yvan! sorry I took time to look into this.
I was able to compile the hard link command on both create hard link and remove hard link script:
here is my complete script (Creating hard link)
on run
--Get the folder
set theFolder to (path to home folder) as text
--Get the path to de destination folder of the files
set destination_folder to POSIX path of (((path to home folder) as text) & "OneDrive -Company Systems Inc")
--Generate the list of files inside theFolder
tell application "Finder"
set theItems to items of folder theFolder
set theNames to {}
repeat with anItem in theItems
set end of theNames to name of anItem
end repeat
end tell
--Let user select the files of the list
choose from list theNames with prompt "Pick the items you want to copy from:" & return & theFolder OK button name "Hard link" cancel button name "Quit" with multiple selections allowed
tell result
if it is false then error number -128 -- cancel
set theChoices to it
end tell
if (count of theChoices) is greater than or equal to 1 then
repeat with aChoice in theChoices
set thisItem to POSIX path of (theFolder & aChoice) as text
do shell script "echo " & thisItem & ""
set newdestiny to POSIX path of (destination_folder & "/" & aChoice) as text
do shell script "echo " & newdestiny & ""
-- do something with thisItem
set the_result to do shell script "/usr/bin/perl -e " & quoted form of ("link " & quote & thisItem & quote & ", " & quote & newdestiny & quote)
end repeat
end if
end run
And this one is to removing hard link:
on run
--Get the folder
set theFolder to (path to home folder) as text
--Get the path to de destination folder of the files
set destination_folder to POSIX path of (((path to home folder) as text) & "OneDrive - Company Systems Inc")
--Generate the list of files inside theFolder
tell application "Finder"
set theItems to items of folder theFolder
set theNames to {}
repeat with anItem in theItems
set end of theNames to name of anItem
end repeat
end tell
--Let user select the files of the list
choose from list theNames with prompt "Pick the items you want to copy from:" & return & theFolder OK button name "Remove Hard Link" cancel button name "Quit" with multiple selections allowed
tell result
if it is false then error number -128 -- cancel
set theChoices to it
end tell
if (count of theChoices) is greater than or equal to 1 then
repeat with aChoice in theChoices
set thisItem to POSIX path of (theFolder & aChoice) as text
do shell script "echo " & thisItem & ""
set newdestiny to POSIX path of (destination_folder & "/" & aChoice) as text
do shell script "echo " & newdestiny & ""
-- do something with thisItem
set the_result to do shell script "/usr/bin/perl -U -e " & quoted form of ("unlink " & quote & newdestiny & quote) with administrator privileges
end repeat
end if
end run