Get Path to Swift Script from Within Script

Get path to Swift script from within script

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)
}
}

Run swift script inside bash script

You can call swift - to read the source from standard input,
and a "here document"
to provide the inline Swift code.

Example: Contents of x.sh:

echo "Before running Swift"
xcrun swift - /path/path2/path3/path4 <<'EOF'
import Foundation

let path = CommandLine.arguments[1]
print(path)
EOF
echo "After running Swift"

Running the script:


$ bash x.sh
Before running Swift
/path/path2/path3/path4
After running Swift

Or, if you want to read the Swift code from a variable:

APP="
import Foundation

let path = CommandLine.arguments[1]
print(path)

"

echo "Before running Swift"
xcrun swift - /path/path2/path3/path4 <<< "$APP"
echo "After running Swift"

Execution Path for Swift Script

When you run yourScript, in Terminal.app, do you more or less $> ./yourScript, right?

When, do you for instance a cd, you can do cd ./thePathYouWant, right? ./thePathYouWant is a parameter (also named launch arguments or options)

In your Swift script, you can read that retrieve all the parameters with CommandLine.arguments.

Now, I guess that you script needs to know some folder or some file before acting.

So, in a simplified way, of launching your script like that:

./yourScript ./Folder/File

You can read ./Folder/File with CommandLine.

Now, you can check if you find File at that path.

The whole logic could be in pseudo code:

// Parameter Path was provided, and is "correct"
if let parameterPath = parameterPath, checkExistenceOfFile(at: parameterPath) {
//Work normally
// Parameter path was not provided or incorrect, we check if the file exists at this level
} else if checkExistenceOfFile(at: "./File") { //"./File" being the default path, we expect it to be launch at the same level
//Work normally
// We couldn't find the path
} else {
print("File not not found, you can execute the script like this: $>\n./yourScript ./Folder/File where "./Folder/File" is the path of the file, or execute $>./yourScript where the file is on the same folder
}

Reliable way for a Bash script to get the full path to itself

Here's what I've come up with (edit: plus some tweaks provided by sfstewman, levigroker, Kyle Strand, and Rob Kennedy), that seems to mostly fit my "better" criteria:

SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"

That SCRIPTPATH line seems particularly roundabout, but we need it rather than SCRIPTPATH=`pwd` in order to properly handle spaces and symlinks.

The inclusion of output redirection (>/dev/null 2>&1) handles the rare(?) case where cd might produce output that would interfere with the surrounding $( ... ) capture. (Such as cd being overridden to also ls a directory after switching to it.)

Note also that esoteric situations, such as executing a script that isn't coming from a file in an accessible file system at all (which is perfectly possible), is not catered to there (or in any of the other answers I've seen).

The -- after cd and before "$0" are in case the directory starts with a -.

Is there a way to have a Swift script use multiple files

There's a better way!

#!/usr/bin/swift -frontend -interpret -enable-source-import -I.

import other_file // this imports other_file.swift in the same folder

funcFromOtherFile()

if you want to import files from ExampleFolder it would be like:

#!/usr/bin/swift -frontend -interpret -enable-source-import -I./ExampleFolder

import other_file // this imports ./ExampleFolder/other_file.swift

funcFromOtherFile()

How to get the current directory in iCloud Drive of macOS with Swift script?

You need to encode the string since it contains a space

path = "/Users/myname/Library/Mobile Documents/com~apple~CloudDocs/MyScripts"
if let encoded = path.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
let url = URL(string: encoded) {
print(url)
}

/Users/myname/Library/Mobile%20Documents/com~apple~CloudDocs/MyScripts"

How do I run a terminal command in a Swift script? (e.g. xcodebuild)

If you don't use command outputs in Swift code, following would be sufficient:

#!/usr/bin/env swift

import Foundation

@discardableResult
func shell(_ args: String...) -> Int32 {
let task = Process()
task.launchPath = "/usr/bin/env"
task.arguments = args
task.launch()
task.waitUntilExit()
return task.terminationStatus
}

shell("ls")
shell("xcodebuild", "-workspace", "myApp.xcworkspace")

Updated: for Swift3/Xcode8



Related Topics



Leave a reply



Submit