Determine path of the executing script

前端 未结 28 2489
再見小時候
再見小時候 2020-11-22 08:01

I have a script called foo.R that includes another script other.R, which is in the same directory:

#!/usr/bin/env Rscript
message(\         


        
相关标签:
28条回答
  • 2020-11-22 08:30

    I would use a variant of @steamer25 's approach. The point is that I prefer to obtain the last sourced script even when my session was started through Rscript. The following snippet, when included on a file, will provided a variable thisScript containing the normalized path of the script. I confess the (ab)use of source'ing, so sometimes I invoke Rscript and the script provided in the --file argument sources another script that sources another one... Someday I will invest in making my messy code turns into a package.

    thisScript <- (function() {
      lastScriptSourced <- tail(unlist(lapply(sys.frames(), function(env) env$ofile)), 1)
    
      if (is.null(lastScriptSourced)) {
        # No script sourced, checking invocation through Rscript
        cmdArgs <- commandArgs(trailingOnly = FALSE)
        needle <- "--file="
        match <- grep(needle, cmdArgs)
        if (length(match) > 0) {
          return(normalizePath(sub(needle, "", cmdArgs[match]), winslash=.Platform$file.sep, mustWork=TRUE))
        }
      } else {
        # 'source'd via R console
        return(normalizePath(lastScriptSourced, winslash=.Platform$file.sep, mustWork=TRUE))
      }
    })()
    
    0 讨论(0)
  • 2020-11-22 08:30

    By looking at the call stack we can get the filepath of each script being executed, the two most useful will probably either be the currently executing script, or the first script to be sourced (entry).

    script.dir.executing = (function() return( if(length(sys.parents())==1) getwd() else dirname( Filter(is.character,lapply(rev(sys.frames()),function(x) x$ofile))[[1]] ) ))()
    
    script.dir.entry = (function() return( if(length(sys.parents())==1) getwd() else dirname(sys.frame(1)$ofile) ))()
    
    0 讨论(0)
  • 2020-11-22 08:31

    Here there is a simple solution for the problem. This command:

    script.dir <- dirname(sys.frame(1)$ofile)
    

    returns the path of the current script file. It works after the script was saved.

    0 讨论(0)
  • 2020-11-22 08:31

    This works for me

    library(rstudioapi)    
    rstudioapi::getActiveDocumentContext()$path
    
    0 讨论(0)
  • 2020-11-22 08:33

    99% of the cases you might simply use:

    sys.calls()[[1]] [[2]]
    

    It will not work for crazy calls where the script is not the first argument, i.e., source(some args, file="myscript"). Use @hadley's in these fancy cases.

    0 讨论(0)
  • 2020-11-22 08:34

    I had issues with the implementations above as my script is operated from a symlinked directory, or at least that's why I think the above solutions didn't work for me. Along the lines of @ennuikiller's answer, I wrapped my Rscript in bash. I set the path variable using pwd -P, which resolves symlinked directory structures. Then pass the path into the Rscript.

    Bash.sh

    #!/bin/bash
    
    # set path variable
    path=`pwd -P`
    
    #Run Rscript with path argument
    Rscript foo.R $path
    

    foo.R

    args <- commandArgs(trailingOnly=TRUE)
    setwd(args[1])
    source(other.R)
    
    0 讨论(0)
提交回复
热议问题