I'm writing a script in Swift, and I want it to modify some files that always exist in the same directory as the script itself. Is there a way to get the path to the script from within itself? I tried:
print(Process.arguments)
But that outputs only the path that was actually given to the script, which may be the fully resolved path, just the file name, or anything in between.
I'm intending the script to be run with swift /path/to/my/script.swift
.
Typically, $0 is used to get the script's path; however, this doesn't always work. So a more reliable or robust way of getting the relative path of the script is by using ${BASH_SOURCE:-$0}. Suppose for one instance that I write echo ${BASH_SOURCE:-$0}, the result I get is ./script.sh.
Compiling your Swift file and executing it from Xcode is as easy as doing it from the terminal. All you need to do is define a New Run Script Phase and add the commands you executed on the terminal into it. From the Project navigator, select the project file.
Swift can definitely be a great choice for writing scripts and other kinds of command line tools that are used to build and distribute a Swift-based app.
Luckily there is a command called realpath that will calculate and print the absolute path of a given path. $0 is the name of the current script as it was executed. So if we run the script as ./examples/shell/absolute.sh then that will be the content of $0. realpath prints the abosulte path.
just in swift:
let cwd = FileManager.default.currentDirectoryPath
print("script run from:\n" + cwd)
let script = CommandLine.arguments[0];
print("\n\nfilepath given to script:\n" + script)
//get script working dir
if script.hasPrefix("/") { //absolute
let path = (script as NSString).deletingLastPathComponent
print("\n\nscript at:\n" + path)
} else {
let urlCwd = URL(fileURLWithPath: cwd)
if let path = URL(string: script, relativeTo: urlCwd)?.path {
let path = (path as NSString).deletingLastPathComponent
print("\n\nscript at:\n" + path)
}
}
The accepted answer doesn't work in Swift 3. Also, this is a more straightforward approach:
import Foundation
let currentDirectoryURL = URL(fileURLWithPath: FileManager.default.currentDirectoryPath)
let url = URL(fileURLWithPath: CommandLine.arguments[1], relativeTo: currentDirectoryURL)
print("script at: " + url.path)
However, it has the same problem pointed out by @rob-napier, if the script's directory is in your PATH.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With