Skip to content

UNC windows path beginning with backslashes: normalizePath bug??

6 messages · Uwe Ligges, Henrik Bengtsson, Keith Jewell

#
Hi,

Back in June I posted the message below, but had no replies. I've made a 
little progress since then so this is to update anyone interested (!) and to 
ask for comments.

Brief problem statement:
Under Windows, some parts of R don't handle UNC paths beginning with 
backslashes. Specifically
a) Sys.glob() fails to find some files breaking (e.g.) Rcmdr plugins
       Sys.glob(file.path(.libPaths(), "*/etc/menus.txt"))
   fails to find files which are there

b) update.packages(ask='graphics') fails when copying the updates into the 
destination folders

In Renviron.site I define the site library with forward slashes, not 
backslashes thus...
   R_LIBS_SITE=//campden/shares/workgroup/stats/R/library/%v
... but the startup process seems to replace them with forward slashes.
I guess because  .libPaths with a 'new' argument calls normalizePath which 
changes leading slashes to backslashes, even with winslash="/"
[1] "\\\\campden/shares/workgroup/Stats/R/library"

I've corrected (??) this by inserting a line into Rprofile.site
  assign(".lib.loc", gsub("\\", "/", .libPaths(), fixed=TRUE), 
env=environment(.libPaths))
That seems to fix problem (a) above, which was affecting a number of users.
But have I broken anything else?

I'm still experiencing problem (b).
I'm the only person on site who updates packages so I've mapped a drive 
letter (L:) and in my own .Rprofile I have a line
   assign(".lib.loc", sub("//campden/shares/workgroup/Stats", "L:", 
.libPaths(), ignore.case = TRUE), env=environment(.libPaths))

So that's OK as far as it goes, but it's all a bit messy!
If .libPaths is called with a 'new' argument it will breaks things again.
normalizePath seems to produce paths that don't work with Sys.glob.

I have the feeling I'm being silly and making hard work of all this.

Any comments? Suggestions?

Best regards, and thanks in advance/

Keith Jewell

"Keith Jewell" <k.jewell at campden.co.uk> wrote in message news:...
#
This is extremely tricky since Windows does not always accept "//" 
rather than "\\". Additionally, there is not implemented system call in 
Windows, hence ?Sys.glob tells us a "partial emulation" is provided and 
"An attempt is made to handle UNC paths starting with a double backslash."

As you have seenm this does not work everywhere, therefore it is 
advisable to run R from mapped drives - as I am doing in the network of 
our university for 13 years without problems now.

Best,
Uwe Ligges
On 11.08.2011 18:29, Keith Jewell wrote:
#
Thanks Uwe.

I'm aware (and have been forcefully reminded) that using a mapped drive 
avoids these problems. But there is no single drive letter which I can use 
site-wide, so I have problems with things like R_LIBS_SITE. As I've outlined 
I'm exploring a range of solutions, including mapping a drive where I can.

I posted in the hope of learning from and perhaps helping those with similar 
problems. I hope that it is permissible to discuss non-canonical use of R on 
this list, I certainly did not intend disrespect for the R developers (or to 
make typing errors).

Best regards

Keith Jewell

"Uwe Ligges" <ligges at statistik.tu-dortmund.de> wrote in message 
news:4E44091E.7090309 at statistik.tu-dortmund.de...
6 days later
#
Just to close this off, in case it helps anyone else in a similar 
situation...

Background: I have R installed on a UNC share with a site library named by 
major and minor version, thus:
\\campden\shares\Workgroup\Stats 'root'
\\campden\shares\Workgroup\Stats\R  base for R related things
\\campden\shares\Workgroup\Stats\R\R-2.13.1 one R installation
\\campden\shares\Workgroup\Stats\R\library site libraries go here
\\campden\shares\Workgroup\Stats\R\library\2.13 site library for R 2.13.x

I took the hint and mapped a drive from which to start R.
Because I don't have a pre-determined drive letter to use I wrote a little 
.bat file to do the job:
------------------
REM find or 'net use' a drive mapped to stats share
set remote=\\campden\shares\Workgroup\Stats
set drive=
:check
for /f "delims=*" %%a in ('net use ^| find "%remote%"') do set drive=%%a
if not defined drive net use * %remote% /persistent:NO>nul & goto check
set StatsDrive=%drive:~13,2%
REM using that drive
REM a) ensure GTK+ is in the path (for packages such as 'playwith')
REM b) start 32 bit R
set path=%StatsDrive%/R/GTK+/bin;%path%
start %StatsDrive%\R\R-2.13.1\bin\i386\Rgui.exe
----------------------------------------
That's a bit flakey, depending on the exact format of the output from 'net 
use'. If anyone has a better solution, I'll appreciate it!

Now the site library:
Putting a UNC path into Renviron.site thus...
  R_LIBS_SITE=//campden/shares/workgroup/stats/R/library/%v
... was the cause of my original problem.
I can't put it in as a mapped drive, because I don't know the drive until 
run time.
I tried to work up and down from the drive mapped R_HOME...
  R_LIBS_SITE=${R_HOME}/.../library/%v
... but that didn't work in Renviron.site.
[1] "Z:/R/R-2.13.1"
... which is fine, but...
[1] "Z:RR-2.13.1/.../library/2.13"
I think this may be something to do with this quote from ?Startup...
"value is then processed in a similar way to a Unix shell: in particular the 
outermost level of (single or double) quotes is stripped, and backslashes 
are removed except inside quotes"
...but I don't have any control over R_HOME, specifically how and when 
forward- or back-slashes are used or removed.

In the end I used Renviron.site just to pass the version information...
   R_Libs_Site=%v
That directory doesn't exist so doesn't get added to .libPaths()
In Rprofile.site I worked up and down from R_HOME...
  .libPaths(file.path(dirname(R.home()),"library",Sys.getenv("R_Libs_Site")))
... which seems to do the job.

It isn't pretty, and the .bat file will probably need changing in future 
versions of Windows.
But by the time R has started there isn't a UNC path in sight.
I still think I've probably re-invented a wheel and ended up with something 
square, but it is going round.

Best regards,

Keith Jewell

"Keith Jewell" <k.jewell at campden.co.uk> wrote in message 
news:j22q11$9u9$1 at dough.gmane.org...
#
I think you can also do this from within R (e.g. in your .Rprofile)
using the R.utils package;

library("R.utils")
System$mapDriveOnWindows("K", "\\\\campden\\shares\\Workgroup\\Stats")
driveLetters <- System$getMappedDrivesOnWindows()
System$unmapDriveOnWindows("K")

These methods utilize 'subst' of MS Windows.

/Henrik
On Thu, Aug 18, 2011 at 6:12 PM, Keith Jewell <k.jewell at campden.co.uk> wrote:
#
Thanks Henrik, but I have 2 reasons for not using that approach:

A) If I don't map the drive until after R starts the UNC path is already 
present in several places I know about and probably some I don't, leading to 
the problems I started with.

So reason 'B' doesn't really matter to me, but as author of R.utils you may 
be interested that...
B) On my system those calls don't seem to work. Details here...
--------------------------
Loading required package: R.oo
Loading required package: R.methodsS3
R.methodsS3 v1.2.1 (2010-09-18) successfully loaded. See ?R.methodsS3 for 
help.
R.oo v1.8.1 (2011-07-10) successfully loaded. See ?R.oo for help.
R.utils v1.7.8 (2011-07-24) successfully loaded. See ?R.utils for help.
R version 2.13.1 (2011-07-08)
Platform: i386-pc-mingw32/i386 (32-bit)

locale:
[1] LC_COLLATE=English_United Kingdom.1252
[2] LC_CTYPE=English_United Kingdom.1252
[3] LC_MONETARY=English_United Kingdom.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United Kingdom.1252

attached base packages:
 [1] datasets  grDevices splines   graphics  stats     utils     tcltk
 [8] tools     methods   base

other attached packages:
 [1] R.utils_1.7.8      R.oo_1.8.1         R.methodsS3_1.2.1  RODBC_1.3-3
 [5] tree_1.0-29        nlme_3.1-102       MASS_7.3-14 
xlsReadWrite_1.5.4
 [9] svSocket_0.9-51    TinnR_1.0.3        R2HTML_2.2         Hmisc_3.8-3
[13] survival_2.36-9

loaded via a namespace (and not attached):
[1] cluster_1.14.0  grid_2.13.1     lattice_0.19-31 svMisc_0.9-61
#  It seems to think I have no mapped drives....
named character(0)
# Although I clearly have (in fact I'm running R from Z:), so I can't
# find a 'spare' drive letter
New connections will not be remembered.

Status       Local     Remote                    Network
-------------------------------------------------------------------------------
OK           F:        \\server10\microbiology   Microsoft Windows Network
OK           L:        \\server23\Stats          Microsoft Windows Network
OK           M:        \\server10\jewell         Microsoft Windows Network
OK           Q:        \\server04\pccommon (not backed up)
                                                 Microsoft Windows Network
OK           R:        \\server23\Template       Microsoft Windows Network
             Z:        \\campden\shares\Workgroup\Stats
                                                 Microsoft Windows Network
                       \\TSCLIENT\C              Microsoft Terminal Services
                       \\TSCLIENT\D              Microsoft Terminal Services
                       \\TSCLIENT\E              Microsoft Terminal Services
                       \\TSCLIENT\F              Microsoft Terminal Services
                       \\TSCLIENT\G              Microsoft Terminal Services
                       \\TSCLIENT\H              Microsoft Terminal Services
                       \\TSCLIENT\I              Microsoft Terminal Services
                       \\TSCLIENT\L              Microsoft Terminal Services
                       \\TSCLIENT\M              Microsoft Terminal Services
                       \\TSCLIENT\Q              Microsoft Terminal Services
                       \\TSCLIENT\R              Microsoft Terminal Services
The command completed successfully.
#  The commands you cited throw errors...
Error in list(`System$mapDriveOnWindows("K", 
"\\\\campden\\shares\\Workgroup\\Stats")` = <environment>,  :

[2011-08-19 09:16:28] Exception: Argument 'drive' is not a valid drive (e.g. 
'Y:'): K
  at throw(Exception(...))
  at throw.default("Argument 'drive' is not a valid drive (e.g. 'Y:'): ", 
drive)
  at throw("Argument 'drive' is not a valid drive (e.g. 'Y:'): ", drive)
  at method(static, ...)
  at System$mapDriveOnWindows("K", "\\\\campden\\shares\\Workgroup\\Stats")
named character(0)
Error in list(`System$unmapDriveOnWindows("K")` = <environment>, 
`method(static, ...)` = <environment>,  :

[2011-08-19 09:29:09] Exception: Argument 'drive' is not a valid drive (e.g. 
'Y:'): K
  at throw(Exception(...))
  at throw.default("Argument 'drive' is not a valid drive (e.g. 'Y:'): ", 
drive)
  at throw("Argument 'drive' is not a valid drive (e.g. 'Y:'): ", drive)
  at method(static, ...)
  at System$unmapDriveOnWindows("K")

Thanks for your interest,

Keith Jewell
---------------------------------------------
"Henrik Bengtsson" <hb at biostat.ucsf.edu> wrote in message 
news:CAFDcVCQE3uUkmmqSjJ0fpEVfJgrAbrgBT1g8drCXGpnsJebEHw at mail.gmail.com...
I think you can also do this from within R (e.g. in your .Rprofile)
using the R.utils package;

library("R.utils")
System$mapDriveOnWindows("K", "\\\\campden\\shares\\Workgroup\\Stats")
driveLetters <- System$getMappedDrivesOnWindows()
System$unmapDriveOnWindows("K")

These methods utilize 'subst' of MS Windows.

/Henrik

On Thu, Aug 18, 2011 at 6:12 PM, Keith Jewell <k.jewell at campden.co.uk> 
wrote:
<snip>