How to get POSIX path of the current script's

2020-02-11 07:45发布

In AppleScript it’s possible to get the the POSIX path of the folder the current script is located in using this line:

POSIX path of ((path to me as text) & "::")

Example result: /Users/aaron/Git/test/

What’s the JavaScript equivalent?

7条回答
贪生不怕死
2楼-- · 2020-02-11 08:04

Here's a way [NOTE: I NO LONGER RECOMMEND THIS METHOD. SEE EDIT, BELOW]:

app = Application.currentApplication();
app.includeStandardAdditions = true;
path = app.pathTo(this);
app.doShellScript('dirname \'' + path + '\'') + '/';

note the single quotes surrounding path to work with paths with spaces, etc., in the doShellScript

EDIT After being slapped on the hand by @foo for using a fairly unsafe path-quoting method, I'd like to amend this answer with:

ObjC.import("Cocoa");
app = Application.currentApplication();
app.includeStandardAdditions = true;
thePath = app.pathTo(this);

thePathStr = $.NSString.alloc.init;
thePathStr = $.NSString.alloc.initWithUTF8String(thePath);
thePathStrDir = (thePathStr.stringByDeletingLastPathComponent);

thePathStrDir.js + "/";

If you're going to use this string, of course, you still have to deal with whether or not it has questionable characters in it. But at least at this stage this is not an issue. This also demonstrates a few concepts available to the JXA user, like using the ObjC bridge and .js to get the string "coerced" to a JavaScript string (from NSString).

查看更多
Animai°情兽
3楼-- · 2020-02-11 08:15

Use -[NSString stringByDeletingLastPathComponent], which already knows how to remove the last path segment safely:

ObjC.import('Foundation')

path = ObjC.unwrap($(path).stringByDeletingLastPathComponent)

Alternatively, if you prefer the more dangerous life, you could use a regular expression to strip the last path segment from a POSIX path string. Off the top of my head (caveat emptor, etc):

path = path.replace(/\/[^\/]+\/*$/,'').replace(/^$/,'/')

(Note that the second replace() is required to process paths with <2 parts correctly.)

查看更多
孤傲高冷的网名
4楼-- · 2020-02-11 08:19

I think I found a simpler way to get the parent folder without invoking ObjC.

var app = Application.currentApplication();
app.includeStandardAdditions = true;
thePath = app.pathTo(this);

Path(thePath + '/../../')
查看更多
趁早两清
5楼-- · 2020-02-11 08:19

Lots of interesting solutions above.

Here's mine, which does NOT require ObjC, and returns an object with properties likely to be needed.

'use strict';
var oScript = getScriptProp(this);

/*oScript Properties
    Path
    Name
    ParentPath
    Folder
*/

oScript.ParentPath;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

function getScriptProp(pRefObject) {

  var app = Application.currentApplication()
  app.includeStandardAdditions = true

  var pathScript = app.pathTo(pRefObject).toString();
  var pathArr = pathScript.split("/")

  var oScript = {
    Path: pathScript,
    Name: pathArr[pathArr.length - 1],
    ParentPath: pathArr.slice(0, pathArr.length - 1).join("/"),
    Folder: pathArr[pathArr.length - 2]
  };

  return oScript
}
查看更多
forever°为你锁心
6楼-- · 2020-02-11 08:26

Pure JXA code without ObjC involved:

App = Application.currentApplication()
App.includeStandardAdditions = true
SystemEvents = Application('System Events')

var pathToMe = App.pathTo(this)
var containerPOSIXPath = SystemEvents.files[pathToMe.toString()].container().posixPath()
查看更多
别忘想泡老子
7楼-- · 2020-02-11 08:27

So to sum up what I’m doing now, I’m answering my own question. Using @foo’s and @CRGreen’s excellent responses, I came up with the following:

ObjC.import('Foundation');
var app, path, dir;

app = Application.currentApplication();
app.includeStandardAdditions = true;

path = app.pathTo(this);
dir = $.NSString.alloc.initWithUTF8String(path).stringByDeletingLastPathComponent.js + '/';

This is quite close to @CRGreen’s response, however, it’s a bit more terse and I’m importing Foundation instead of Cocoa. Plus, I’m declaring the variables I’m using to avoid accidental globals.

查看更多
登录 后发表回答