Scripting - current directory
Murray Colpman (1746) 7 posts |
I’m just wondering, in a script (Obey file), how would I refer to the current directory? For instance, as a destination to a copy command. EDIT: Actually, experimenting more, I also can’t figure out how to copy multiple files into a directory (it just tries to copy on top of the directory when I try). EDIT2: Ah, finally figured it out. For prosperity:
|
Steve Pampling (1551) 8155 posts |
You found the shorthand shortcuts. If you look at the !Run files in a few applications (usual hold down shift and double click the application directory) you will note the use of Set something$Dir <Obey$Dir> which sets the something$Dir system variable to the canonical name (full path all the dots and bits) of the current directory. BTW. “posterity” rather than “prosperity” (unless you’re counting on making lots of money :) |
Martin Bazley (331) 379 posts |
Steve mangled that explanation a bit. To clarify: % and Obey$Dir are not the same thing. RISC OS has one global variable called the Currently Selected Directory (CSD). You can set this from the command line by typing “Dir (pathname)”, or from the Filer’s menu by clicking the ‘Set directory’ option (or, these days, pressing Ctrl-W, apparently). The character @ has a special meaning in filenames, which is to substitute it with the CSD. Unlike Unix-based systems, the CSD is not local to the currently running task, and it can be changed behind your back, so watch out! Now, RISC OS also has global ‘system variables’, which are written with the “Set varname value” command. Because they are global, to eliminate conflicts, they are usually named according to the convention appname$name, e.g. Paint$Dir. In general, surrounding the name of a variable with angle brackets will substitute the value of that variable (a bit like Unix’s $ operator, except as you can see that character has already been claimed). So you can type “Set varname <varname>” to set a variable to the value of another variable1, type “Dir <varname>” to set the CSD to the value of a variable, or use them in expressions, like "If “<varname>” = “value” Then …". (The double quotes denote string comparison, as variables created with Set will always be strings.) You should remember that this doesn’t work everywhere – generally speaking, filenames and the Set and If statements are the only places where you can guarantee angle brackets to be valid. You’ll have to make special arrangements if you want to read the value of a system variable in most other contexts. When RISC OS opens an Obey file for execution (and not any other type of file, so this only works if your command is in an Obey file), it sets the value of a variable called Obey$Dir to the parent directory of the Obey file’s location. This – and only this – is what enables RISC OS applications to run completely independently of their location on your hard drive. Outside of the !Boot directory, the structure of your hard disc is entirely up to you. (I understand Windows and Linux enforce much stricter conventions.) The first thing most applications do in their !Run file is to copy the initial value of Obey$Dir into a more permanent location, which the application will then refer to throughout its lifespan, using the command “Set appname$Dir <Obey$Dir>”. You can then perform, for example, “Run <appname$Dir>.!RunImage”. The value of the CSD should always be treated as undefined unless you have explicitly set it (and haven’t multitasked since then and aren’t running in a TaskWindow, so you know nobody else could have set it). In particular, I interpret your post to mean that it is set to the location of the parent directory of the Obey file on entry. As I find myself saying to RISC OS newbies so often these days, this ain’t Linux. Always use <Obey$Dir>. 1 This will physically copy the value. To mirror the variable’s current state, including if it later changes, there’s another command: “SetMacro varname <varname>”, which evaluates its argument every time you refer to the newly created variable. You can also create numeric variables using “SetEval”, in which case the double quotes in the If command are no longer necessary, and you can use arithmetic operators, e.g. “SetEval varname <varname> + 1”. EDIT: Ah, I see this old problem has caught you out too. In fact if I hadn’t been bitten by it in the past I probably wouldn’t even have realised my post was wrong. The CSD is referred to by the @ character. % denotes the Currently Selected Library Directory – not necessarily the same thing! A full list of special characters in filenames is available here. |
Murray Colpman (1746) 7 posts |
“BTW. “posterity” rather than “prosperity” (unless you’re counting on making lots of money :)” Er, yes, thanks for that – in my defence I was very tired having stayed up all night finishing my boot menu ;) Thanks for the explanation – I just % by noticing someone used ^ for parent directory and searching around that sort of area of the keyboard so I’m not surprised it isn’t accurate ;). As it turns out, I didn’t use it in my script (I used absolute paths), so that’s fine – this script was running in !Boot and referring to a fixed location ($.!boot.loader to be precise) so it’s not like I’m going against any conventions of portability. Thanks a lot for the help again, but out of interest/for future reference what is the difference between the CSD and the currently selected library directory? Is the latter local to the process/script or is it something different? |
Steve Drain (222) 1620 posts |
You have not mentioned *Prefix, a feature of the DDEUtils module. This sets a CSD for the current task. Very handy. |
Steve Pampling (1551) 8155 posts |
I’d been up for only a few minutes – hence the fluffy explanation… Martin was way better. Steve’s comment may leave you confused unless you happen to have the DDEUtils module (not standard build in RO, added on certain items – like development tools IIRC) |
Steve Drain (222) 1620 posts |
I am sure I have had DDEUtils in !System since at least my first RPC, maybe RO 3.1, and it is in the ROOL distribution. It does have to be RMEnsured, though. It also provides throwback, which I would not be without. |
Steve Pampling (1551) 8155 posts |
So it would seem – that’s obviously why I didn’t notice it was tucked away on the !Boot. RMEnsure DDEUtils 0.00 RMLoad System:Modules.DDEUtils |
Steve Drain (222) 1620 posts |
I suppose for completeness, TaskObey files, &FD7, should be included there. ;-) |