Mail Archives: cygwin/2010/10/29/05:53:12
On Thu, 30 Jul 2009, Eric said
>>> DEVDIR="$(cygpath -au "C:/$(cygpath -am /dev/)" | sed 's|/c/\(.\):/|/\1/|')"
>>> mkdir -p "$DEVDIR" || result=1
>>
>> Hmm, this looks kind of fragile. Not to say it looks wrong.
>
> I didn't invent this, but borrowed the idea from the old mkdev script
> (did Igor write that?). But there is certainly the possibility that
> it can be made more robust, especially in the face of 1.7 mount
> changes. I'll have to take a look at it in depth when I get a chance
> (won't be for two more weeks; right now I'm on vacation with only
> limited email access).
I've not seen any follow up on this issue for some time, and in fact I've just experienced a failure of bash's postinstall script fails due to the strange way DEVDIR is built.
The ultimate goal of that complex expression, is to get the "physical" path of /dev.
On normal setups (i.e. Cygwin installed in a folder called "cygwin" in the root of C: drive), this should be equivalent to:
DEVDIR="/cygdrive/c/cygwin/dev"
On non-standard setups, however, the drive could change and the folder name could change, thus the need for a complex expression.
The point is that this implementation fails even in the normal setup, because, once the $() expression is executed, the whole line becomes:
DEVDIR="/cygdrive/C/cygwin/dev"
Note the capital C!
The problem is that it incorrectly assumes that X:Y:zzz always translates to /cygdrive/x/Y/zzz (pay attention to case), and not to /cygdrive/x/y/zzz, which is more consistent (at least, if X become x, Y should become y). The easy way to correct it is to add a \l (backslash, lower el) before the \1 (backslash, digit one) which instructs sed to lowercase the following character. Here is the complete line:
DEVDIR="$(cygpath -au "C:/$(cygpath -am /dev/)" | sed 's|/c/\(.\):/|/\l\1/|')"
However, I still think this is a inelegant hack, and that the right way to achieve the desired result is to work through these steps:
1) understand the Windows path of the Cygwin root directory:
WINPATH=`cygpath -am /`
2) extract the drive part:
WINDRIVE=${WINPATH:0:2}
or
WINDRIVE=${WINPATH%%:*}:
3) translate the drive to its representation in cygwin:
CYGDRIVE=`cygpath -au $WINDRIVE`
4) in parallel, extract the rest of the path:
REST=${WINPATH:2}
or
REST=${WINPATH#*:}
5) merge the drive part and the rest to get the location of /dev:
DEVDIR=${CYGDRIVE}${REST}/dev
Of course, two lines are enough:
WINPATH=`cygpath -am /`
DEVDIR=`cygpath -au ${WINPATH:0:2}`${WINPATH:2}/dev
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
- Raw text -