#ARexx Current Dir
19 messages in this thread
Hi there. I just picked-up ARexx, and I think it looks pretty good! I've come
across one snag in a script I'm trying to write, and I'm wondering if anyone
has found a way around this problem. How can you get the current;y logged
directory without having the user type it?? ARexx seems to default to ':' as
the current directory (when I was logged into RAM: ???), and it doesn't offer
any function to retrieve the current dir. I've tried using call pragma('d','')
thinking that this would set ARexx's CWD to NULL, thereby placing files in the
correct CWD, but ARexx wouldn't let me do this! It replaced the '' with ':'! I
then tried calling CD without any arguments, and re-directing it's output to a
temp file in RAM:, and then reading it's output from the file, but I got
'DF0:'! Does ARexx internally do a CD : or something like this?? Any ideas?
Bill, you asked for suggestions for improvement in ARexx? Well, here's one! 🙂
Ray
Ray,
Take a look at ARCALL.REXX in the ARexx library here (don't remember library
number). It will handle current dir. It does it by doing an operation like:
variable = pragma('d'), then using the variable as part of any reference to a
file, like: delete variable || 'filename'.
-larry
Larry, I tried the 'var = pragma('d')' command but it always seems to return
':'. I did all my experimenting while I was logged into RAM:, and that command
still returned ':'. Actually, I guess that's correct (I am in the root of
RAM:). What I really need then is the current device. When I try writing a file
with no device specification, it writes to DF0: root dir. What I want is, if
I'm logged into RAM:, I want my file operations to happen in RAM:. If I were
writing in another language like C, assembler or BASIC, this would be the case
and I expect that it should be the same in REXX also, but that doesn't appear
to be happening.
Ray
Ray,
I saw a message from Bill Hawes that talked about this problem, so I imagine
you've seen it by now, but thought I'd add some additional comments. You could,
as a workaround, do something like:
curdir = pragma('d')
if curdir = ':' then curdir = 'RAM:'
Then, whenever you open a file (for read or write), you would use the
expression
curdir || 'filename'
It's a bit of a kludge, but does offer one hidden advantage. If you use a
variable for the 'base directory', you can assign it from either the command
line argument passed, or from a pragma() call. in this way, your program might
work well when called with or without arguments.
-larry
Larry, I suppose that would work if pragma('d') only left-off the device name
for RAM:. I do not know that this is the case. It certainly wouldn't be
appropriate to do that otherwise – could cause some serious problems. I'll have
to check that out a little more. Anyway, I don't see any reason why there
shouldn't be a function in ARexx that returned the correct current working
directory to you. I don't know of any other language that doesn't provide that
ability. Bill wanted suggestions for additions to the ARexx Amiga-specific
function library, and this is mine…
Ray
Ray,
The PRAGMA('D',dir) is intended to return the full name of the current
directory, and the problem with RAM: is just a limitation with the RAM:
handler. To get a path name I call ParentDir() repeatedly to reach the root
node, and use Examine() to get the name at each point. A proper file system is
expected to return the name of the volume as the root, but RAM: is a
pseudo-filesystem and returns a null volume name — hence the :
To the best of my knowledge this will be fixed in 1.3, and you can probably
safely assume that a null volume name will only indicate RAM:.
-Bill Hawes
Ray,
i think the problem lies with the fact that the RAM: device is really not a
device at all, bt a handler. It seems that there are a few idiosyncracies with
it, and often authors must have some sort of exception handler to take RAM:
into account. For instance, the name that RAM: is known by to Amigados is 'RAM
Disk', but don't ever try to do a DIR "RAM: Disk" unless you want a good chance
of having tea with the GURU.
CBM is supposedly going to fix all that in the next release though, so if you
write your workarounds properly now, they will still be good in the future,
when they release it, in about 1996
-larry
I heard it was delayed until 2004, when they get to the Omega release of the
developers versions.
Oh boy….
Come on Ben! You have 1.3. The problems with the ram handler were fixed back
around Feb/Mar in GAMMA 4.
Now! If your griping about the fact that 1.3 is vapor, I understand and agree
with that! 🙂
Dale
Ray:
That is the case! (execpt that I don't think that it is AREXX that is leaving
off the device name). The RAM: handler is different from the 'drive handlers'
and does not respond the same way. Larry's kludge will work ok.
73, bill
Bill, I still haven't had a chance to look into Larry's suggestion any more
yet. IF when logged onto DF0: or DF1: pragma('d') returns the correct device
name, etc., then Larry's suggestion will be fine. I just have one question here
though… If I were to do something similiar in Lattice (ei. open a file with
no device:path), the file would end-up in the correct place. Even RAM: if
that's were I happened to be logged into. So, my question, How does Lattice do
it?
Ray
Ray,
If you are CD'd to RAM: in ARexx and open a file using OPEN() it will accept a
partial path, and open the correct file. It's only when executing commands via
address command xxx that the CD isn't inherited. Within the ARexx task
itself you can change the current directory using pragma(), and the built-in
file I/O functions will work as expected.
Note that the path name returned by pragma uses the volume name rather than the
device name. This is becasue AmigaDOS gives volumes priority over devices —
if you had a volume named DF1 mounted on DF0:, doing a cd df1: would put you on
the volume, not the drive. Thus it would be chancey for me to fill in the RAM:
device name instead of going after the volume name.
Have you tried using VD0: instead of RAM:? It works fine, and you can do an
ASSIGN RAM: VD0: so you don't have to change any script files.
-Bill
Ray,
I also ran into that problem when I first started playing around with ARexx
for CLI scripts. It seems that a new Process is spawned to process the script,
and that process doesn't inherit any of the attributes from the spawning CLI.
So there is no path set up, and the default current directory is the NULL Lock,
which is an implicit DF0:. I found two ways around this problem — the first
was a royal pain, and the second cost money.
My first solution involved building the scripts so that I either
hard-coded everything (including explicit pathing of commands), or used
variables that I passed as parameters when invoking the scripts. This approach
worked well, but I still wasn't crazy about it.
My second solution was much more satisfactory. I sprung for the $50 and
purchased WShell, Bill Hawes CLI shell package. Since it was written by the
person that wrote ARexx, it is designed and implemented as the perfect
complement/companion to ARexx. ARexx scripts are executed automatically, no
need to use the "address command … " syntax to issue an AmigaDOS command, and
the complete inheriting of your current environment (path, current directory,
etc.) auto-magically. I think it's well worth the cost, as it really makes
ARexx a much more powerful and useful tool.
BTW, I am in no way connected with Bill Hawes – just a satisfied customer.
Hope this helps…Bob
Bob,
For an additional technique to avoid 'hard pathing', see the latest
ARCALL.REXX in the ARexx LIB.
-larry
Hi Ray,
The pragma('Directory',dirname) is indeed the function to use, but the RAM:
handler has a bug so that its top level gets reported as ":". This problem
(and many others) are fixed in 1.3, to the best of my knowledge.
When you run a command using the "address command …" instruction, the command
unfortunately doesn't inherit your current dir; it's a long-standing problem
with AmigaDOS's Execute() function. However, a simple workaround is available:
you can issue several commands at once by separating them with a 'newline'
character — '0A'x in REXX. Try the following sequence
address command 'cd df1:c'||'0A'x||'cd'
and it should report df1:c as the current directory. The pragma() function
will return the current directory path.
Hope this helps out, and let me know if you have other questions.
-Bill Hawes
Speaking of Execute() I just got WShell (as well as AREXX) and I see two
executables regarding this function. SetExecute and PatchDOS. What's the diff?
The docs only describe SetExecute.
Also, I understand that RunWSH provides a "path" back to the CLI. This means
that RunWSH'ed programs that Execute() others that require console input can
get it there, right? An example would be a DirUtil that executes ARC and ARC
asks to overwrite an existing file "Y or N?" I can respond from the CLI that
launced the DirUtil. Am I getting that right?
On the other hand, does RunWSH provide a "RunBack" kind of ability? I have
been using the ARP ARun NOIO facility for this.
Finally (This time around. Thanks for your patience), launching a new WSH
from WB (or a PopCLI kind of thing – once I have done SetExecute) obviously
means stuff from older WSH's is not inherited. I have to create a new RESIdent
list. Assuming it's the same, am I using additional memory?
Thanks, Bill. — Art
Hi Art,
PatchDOS and setexecute are identical — I just wanted to give the icon a
descriptive name 🙂 Note these programs are "experimental" — no big
problems, but a few incompatibilities.
Once you've done a patchDOS, programs will inherit cd and path when you do an
Execute(), tho I've heard that some early software was written to assume that
Execute()ed commands would end up in DF0:
You shouldn't need to set up new residnet lists when you reopen a WShell from
WorkBench, unless the library (where resi anchors the stuff) has been purged
from memory. SOme programs (eg DPaint) ask for 10 megs of memory when they
start up, which flushes any unopen but residnet libraries. Is this what you're
observing?
-Bill
Thanks for the response Bill. Thanks for Aexx also while I'm at it! (despite
my confusion||fustrat{\ with this problem, I still think ARexx is a great
product!) I'd like to be able to know that the user is current'y logged onto
RAM: when they execute this script (actually, it's vital to the script's
correct operation). I still don't see how I can do that. I understood from the
documentation that I could say 'call pragma('d','RAM:')' to make RAM: the
current device:directory, but I can't just put that in the script becuase RAM:
may NOT be current. I could be logged into DF1:Source. How can I tell where I
am. From programming in other languages (such as C), I've come to expect that
if I opened a file called 'TEMP.FILE' (which has NO device||directory
specification, that this file would be opened in the current working directory.
It appears that this is not the case, (at least with RAM:) and I don't know any
other way to handle the situation, other than writing this thing in C, which
would of course defeat the whole purpose of having ARexx. So what am I to do???
And of course, WHERE IS 1.3?????????? [Grin]
Thanx again Bill, Ray