Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get path to Swift script from within script

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.

like image 915
Zev Eisenberg Avatar asked Jul 17 '15 16:07

Zev Eisenberg


People also ask

How do I find the script path?

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.

How do you compile and run a script in one step in Swift?

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.

Can you script with Swift?

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.

Where is absolute path in bash shell?

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.


2 Answers

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)
    }
}
like image 28
Daij-Djan Avatar answered Sep 21 '22 14:09

Daij-Djan


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.

like image 55
ganzogo Avatar answered Sep 21 '22 14:09

ganzogo