2015-07-17 8 views
9

Piszę skrypt w Swift i chcę go zmodyfikować niektóre pliki, które zawsze istnieją w tym samym katalogu, co sam skrypt. Czy istnieje sposób, aby uzyskać ścieżkę do skryptu z samej siebie? Próbowałem:Uzyskaj ścieżkę do skryptu Swift z poziomu skryptu

print(Process.arguments) 

Ale to wyjść tylko ścieżkę, która została faktycznie przekazane do skryptu, który może być w pełni rozwiązany drogą, tylko nazwę pliku, lub coś pomiędzy.

Mam zamiar uruchomić skrypt z swift /path/to/my/script.swift.

Odpowiedz

4

tylko w 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) 
    } 
} 
+1

Pamiętaj, że to się nie powiedzie, jeśli użyjesz # #! i jest w PATH (ale pasuje do sposobu, w jaki OP mówi o uruchomieniu skryptu, więc to jest w porządku) –

+0

@RobNapier co masz na myśli? Mam '#!/Usr/bin/env swift' na górze, ale to nie jest w moim' $ PATH' –

+0

Mam na myśli, jeśli script.swift jest w Twojej PATH, to po prostu wywołanie "script.swift" sprawi, że wygląda na to, że skrypt znajduje się w jakimkolwiek katalogu, w którym aktualnie się znajdujesz. –

5

Zaakceptowanych odpowiedź nie działa w Swift 3. Poza tym jest bardziej proste podejście:

import Foundation 

let currentDirectoryURL = URL(fileURLWithPath: FileManager.default.currentDirectoryPath) 
let url = URL(fileURLWithPath: CommandLine.arguments[1], relativeTo: currentDirectoryURL) 
print("script at: " + url.path) 

Jednakże, ma ten sam problem wskazał przez @ rob-napier, jeśli katalog skryptu znajduje się w Twojej PATH.

+0

To działa prawie idealnie w Swift 3, ale 'CommandLine.arguments [0]' zawiera nazwę skryptu (w pytaniu Zeva). Chcesz 'CommandLine.arguments [1]', który zawierałby nazwę przekazanej ścieżki/skryptu. – worthbak

+0

@worthbak: masz rację - zaktualizowałeś – ganzogo