malxau/yori

If ErrorLevel / Is Yori Elevated ?

Closed this issue · 20 comments

Hello.. I'm new to Yori.. I'm enjoying its simplicity, useful completions, and (thank you for) the aliases.
But I do have some pretty basic issues:

  1. Is there a way to use ERRORLEVEL within an IF statement?..

And:

  1. Is there a way to determine from a .ys1 script (Init file) if the current shell is running with elevation?

I usually do this in CMD by running any command that requires elevation, which sets the ErrorLevel.. for example:

$ net session>nul 2>&1
$ if ErrorLevel == 0 (Echo We have elevation)

But in a Yori script (Init file) it seems neither if statements, nor the ErrorLevel can be used (conditionally) at all.. Even calling an external script .cmd for this task seems not to work.. Or is there currently a way to do it?

Nevermind.. I was able to detect elevation with this command:

$ If net session >nul 2>&1 ; Set IsAdminRun=YES ; Set IsAdminRun=NO

This seems to work... However, it seems the %IsAdminRun% var can't be used within any IF statement.. !?
Are there any plans to implement IF %var% ?

This is what I ended up with:

Set WSYSTEM=YCMD
Set YORIPROMPT=$_$$E$[105m %WSYSTEM%
If net session >nul 2>&1 ; Set YORIPROMPT=%YORIPROMPT%⛊
Set YORIPROMPT=%YORIPROMPT%$S$$E$[43m$E$[30m $P$$E$[90m $E$[0m$_$ϟ$S$

I do this with every shell (Cmd, Bash, Pwsh, Git) so I can go back and forth with ease..

2021-06-26 15 14 45

Firstly, that's a really nice prompt! As you've probably seen, the default includes $G_OR_ADMIN_G$ which is not as visually impressive but is still attempting to convey the same information.

If has been a bit painful because the CMD grammar for it is so inconsistent. It's one area where Yori does something very different to CMD, and is much closer to bash. Each test is invoking a child program of some kind. Errorlevel is accessible via %ERRORLEVEL%. So something like this should work:

c:\>true
c:\>if intcmp %ERRORLEVEL%^>=1; echo Command failed!
c:\>false
c:\>if intcmp %ERRORLEVEL%^>=1; echo Command failed!
Command failed!

Yori also includes a command whose intended purpose is to answer the question of whether the user is elevated: grpcmp.

C:\>if grpcmp Administrators; echo User is admin
...
C:\»if grpcmp Administrators; echo User is admin
User is admin

Note the second case is indicating an admin prompt via the prompt char.

@malxau yes!.. I noticed $G_OR_ADMIN_G$ but it didn't allow a custom string (which wouldn't be a bad idea to implement)..

I understand the problem with IF.. It is painful to use in CMD, mainly because there are no AND/OR logical operators and code can get quite messy when batch files grow over time. I've also never liked parentheses as separator for code blocks. I actually think the semicolon (;) for single line conditionals is better..

Because IF is not yet fully implemented I also think you'd be in a unique position to do it differently (if desired). I don't think it's on the roadmap, but if there's ever the decision to implement more complex control statements (IF-ELSE-ELSEIF-SWITCH-WHILE) [yeah I know I'm on the wrong lane here], please consider using Curly brackets {} for code blocks, and parentheses () to optionally group conditional blocks (in the likes of C) .. I mean, there's already CMD.exe and Yori runs batch files with it.. I know there are already many scripting languages. But I've always thought a full replacement for CMD could be both backwards compatible (which Yori does by executing batch files with CMD) and implement new features found in other scripting languages. But these are just ideas.

The "intcmp" and "grpcmp" solutions worked for me (I just didn't see them documented), BUT.. In the case of "grpcmp" it's language dependent.. So since my default Windows language is spanish, the command:

$ if grpcmp Administrators; echo User is admin

..Fails even when executed from an elevated prompt, so it would have to be used like this:

$ if grpcmp Administradores; echo User is admin

But I don't think relaying on locale is a good idea..

One other thing..

I also noticed these two issues with Yori:

1. Using the | symbol within a Rem comment breaks the script:

Rem | This is a comment that breaks things
Rem ^| This is an ugly comment that won't breaks things

I usually add a separator from Rem and any comment; CMD ignores everything after Rem..

2. There's a problem with CHDIR/CD and slashes/backslashes in directories..

These commands fail (but they work on CMD.exe):
$ cd /
$ cd "dir/"
$ cd "dir\"
$ cd "/Workspace"
$ pushd /Workspace

Then these commands work:
$ cd \
$ cd dir/
$ cd dir\
$ cd "\Workspace"
$ pushd "\Workspace"

I think this is unwanted behavior !?.. I do think CHDIR should be more flexible with slashes..

  1. grpcmp -b can be used to check for group membership in a locale independent way. Because this requires Yori to know the group by ID as opposed to name, it can only work for well known groups, and as of now, that means only one group: Administrators.
  2. I've been trying to bring a little more consistency to the grammar than CMD allows, which I think will make things simpler both to implement and to use, but it exposes some of the special-casing that CMD had. In Yori, rem is a command, and has the same behavior as any other command. Implementing it to ignore command separator operators means it's not just a command: it's magic that tells the parser how to interpret command separators. CMD is full of this type of thing, but it's worth thinking very carefully about whether this is really a good road to start going down. There will always be commands that benefit from special casing, but the result is a language that can only be reasoned about by awareness of every case.
  3. Yori still has the same problem that DOS has, where the choice to use / as a switch to commands means it cannot simultaneously unambiguously be a path separator. This is why DOS used backslashes for directories, because forward slashes already referred to command switches when directories were added. What CMD is doing here is interpreting forward slashes as path separators except if they are known switches, which means /c is a path but /d is a switch, and it cannot add new switches without breaking compatibility. Again, this is simple enough in terms of code change, but think carefully about whether this is a good road to go down. Note the same issue will affect all of the Yori tools that reason about paths.

So in Yori, cd /, cd "/Workspace", and pushd /Workspace are all referring to switches, and an unknown switch triggers a prominent warning rather than being interpreted as a directory.

cd "dir\" is hitting the parsing logic described in https://docs.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments where the backslash is escaping the quote, resulting in cd dir". I really don't like this parsing logic, and only implemented it in Yori recently (which doesn't use the Microsoft C runtime so the link above isn't exactly binding), but just like the cases above, it seems better to be consistently goofy than to have different rules in different places. The discussion for this is in #83 which is a bit hard to follow because I think we were both trying to understand the logic as much as implement it.

cd "dir/" is something I'd expect to work - it appears to work for me. What error is it giving you?

  1. Well, grpcmp -b works perfect and now I'm using it.. Thank you!.. Is good to have a native implementation for this purpose. I think it would be a good idea to add that information to both the online documentation and the command help (like, expressly indicate what can be done with it, with the example you showed me).

  2. Ok, I understand (in Yori Rem is a command vs. CMD grammars).. But is there a point to allow redirection (>) and pipe (|) characters in a comment?.. I think maybe.. but then I'd say Yori scripts need a pure comment character like ; or # where everything is ignored afterwards (when used outside double quotes). This would allow to freely comment about redirections and pipes without hitting a wall. Or to just use those characters in the comment. Just a thought, nothing critical here.

  3. I see.. that makes sense (\ vs. /).. Whatever you decide about this it's ok with me.. But I do like to use / while moving around because to use \ requires me to use the AltGr key to access that character, which makes things a bit slower. And sometimes I miss and write a different character. Other people may experience the same. Also, enabling the YORICOMPLETEWITHTRAILINGSLASH option makes things break, because every directory with spaces you try to access will autocomplete to CD "DIR NAME\" and after pressing [ENTER] you get an error. I believe this is unwanted behavior. I think one of the two things should be addressed, either the YORICOMPLETEWITHTRAILINGSLASH option is removed or commands like CD "DIR NAME\" (preferred ?) should be handled. BTW.. cd "dir/" is working for me.. not sure why I included that one.

2021-06-27 05 38 17

2.1. I just noticed that if I keep pressing [TAB] the folder name keeps repeating and the command is invalid (with YORICOMPLETEWITHTRAILINGSLASH enabled and only the folder "DIR TEST" in the current path location):

2021-06-27 05 47 11

  1. I think is important that the current usage of IF and any other control flow statement is documented in the online help (like, in its own section) and also in the command help. I know the /? switch gives some information similar to CMD, but I think they should indicate a little more about what they can do and what they can't.. So as to not have new people come in to try and guess. Even if things are experimental it would be a good thing to know that. I mean, when I first tried Yori I was surprised by how well it handled completion and aliases, but I kind of hit a wall when I first tried the IF statement.

  2. QUESTION: Is there a way to know if a Yori script is running from an interactive shell or not?

  3. QUESTION ANSWERED: Is there a way to natively implement IF EXIST in a Yori script:

Based on your example with intcmp I checked the source files and noticed there are other useful commands like strcmp and fscmp. Man, those are pretty cool...

$ if fscmp -d "D:\Workspace" ; Echo Folder exists ; Echo Folder does not exist
$ if fscmp -f "D:\Workspace\Logfile.txt" ; Echo File exists ; Echo file does not exist
$ if strcmp -i [%var1%]==[%var2%] ; Echo Variables are the same ; Echo Variables are different

I think it would be a great idea to have them documented in the online help. I'm in shock they're not mentioned.

Can we get strlen, strchr and strstr too ? 😁

  1. Both the guide and individual command help texts are checked in to GitHub, which specific changes are you suggesting? The meta problem with documentation is how to have something that's concise enough to be read and descriptive enough to cover common problems. Unfortunately the implication is that less common situations can't be fully described.
  2. Just note what happens when a comment exists inside something truly compound, like a for or if. Is the intention really to discard everything that follows to the end of the line? Should it be invalid to include a comment inside what can be horrifically long multi-expression commands?
  3. Agree that the behavior of YORICOMPLETEWITHTRAILINGSLASH is quite broken after treating backslash prior to quote as an escape. Unfortunately fixing it is a bit of a pandora's box - the double backslash is only a valid escape if it immediately precedes a quote, so if the prompt is saying dir "C:\Program Files\\" and the user presses 'x', the result should be dir "C:\Program Files\x". Yori tried to emulate Cmd's logic about treating "C:\Program Files\"folder as if the quote extends across the entire text, but the two ended up quite different. Cmd does this for tab completion; Yori does it everywhere, so you can just type after a previous tab completion and the child process receives a complete path. But what this implies is that \\" in the middle of text needs to become \ whenever a quote is moved to the end by the shell, but retained when the quote is retained. I'm working on changes for this but it's going to be relatively large. What's really crazy is that since Windows gives the child process the entire string (as opposed to an argc/argv array as Unix does), there's no way for the shell process to know which conventions the child is expecting, so some tools will want "C:\Program Files\\" and some want "C:\Program Files\" . Then again, people using YORICOMPLETEWITHTRAILINGSLASH already have the problem that not every tool wants a trailing slash either.
  4. Similar to 0, which changes here are you proposing? I think the high level issue is having if link to strcmp, intcmp, fscmp, and grpcmp in some way, although part of the point of if working the way it does is any comparison program can be used.
  5. I don't understand this question. What is an interactive shell in this context? To me an interactive shell is something that the user is typing commands into, and the existence of a script implies that execution is no longer interactive, so this question implies there are two scenarios in which scripts are executing, one being more interactive than the other.
  6. strcmp has a kind of strstr using *=, which is really the same thing as strchr given the lack of a native character type. There's no strlen, although bash has some things that come close. It's common enough in bash to see scripts that say "test if this string is empty" by using -z meaning it has zero length rather than comparing it to a literal empty string.

Hi again!

  1. The first time I tried out Yori there were two things I was looking for in the online documentation that I did not find. A complete list of available commands and tools, and actual scripting examples with the available control flow statements (IF, GOTO, FOR), all of which have obvious differences from the CMD implementation. If I had not ask here or check out the sources, I wouldn't have found grpcmp strcmp or intcmp; in fact, the first thing I tried was an IF statement ala CMD, but it didn't work and I was ready to move on. I would suggest those two sections for the online documentation: A list of commands/tools available, and Control flow statements (with examples using tools like grpcmp, strcmp and/or intcmp). I don't personally need it now, but I believe your project will benefit greatly from it.

  2. I'm not sure I follow the idea, but I might be wrong.. I just know that I tend to document everything, and that can be a small brief or a lot of writing. Having to check if a script is broken every time I make a comment doesn't seem like a good idea to me. I would have to find an actual benefit from having pipes, redirections or other potential options in a commented out line. I would even make the case for having comments after commands or statements (in the same line). But I do understand your point.

  3. Got it!.. I kinda hope it gets solved in the future, but I've disabled the option and is working fine. It's one of those things you wouldn't complain or even know about if the option wasn't available.

  4. Same as 0.. Being concise is good, but listing commands and statements available is better, and saves a lot of time. Examples are important, and most of the time is where the fun is. Just saying!.

  5. Yes, that's precisely what I mean by interactive shell. You enter in interactive mode when you type in commands and expect responses and outputs, and non-interactive when running scripts. It's useful to know when a script is running non-interactive so we can skip init scripts, global functions and aliases to make it load faster (in some cases this can make quite a dramatic difference).. It also helps when we want a welcome message in interactive mode, or after a login. In both Bash and Zsh we can use the $- variable to find out if they're running in interactive mode, in Csh with a $?prompt conditional, in Fish with status is-interactive, in PowerShell by parsing GetCommandLineArgs(), and CMD sets the environment var %CMDCMDLINE% with the option /K when running in interactive mode.. But I haven't find yet something I can use with Yori.. !?

Have a great week!

Sorry for the delayed response. I've been working on fixing 2, and although the final change is fairly small, it took a few attempts to get there.

This change adds the required escapes before a terminating quote as part of tab completion. The parser has been modified so that when a quote is being swallowed (because it is followed by more text) the escapes are removed. This allows the user to type text after a tab completion, possibly invoking tab completion again, and have the result not contain redundant escapes.

For the documentation changes, I understand where you are coming from, but changes require specific text to change to specific values. If there are clear things that would have made things easier for you, please submit a PR that shows the text changes you'd like to see.

I'm still unclear on the interactive shell issue. I know other shells make a distinction here, but are you saying the purpose of the distinction is to avoid running expensive init scripts, so a non-interactive instance is the same as an interactive one but with less initialization? Presumably scripts need to be defensive to operate correctly if the extra initialization is performed, so this isn't an environment scripts rely on, it's a performance optimization? Although users can add as much initialization as they'd like, the default configuration is to have tools prefixed with "y" so they can be called from CMD, and aliases to these defined within Yori so the environment functions with familiar commands. Skipping this initialization means scripts would need to add a lot of "y" to be robust to running without aliases.

Some aliases are defined explicitly in code, as opposed to initialization scripts. See things like:

yori/sh/yoristd.c

Lines 196 to 203 in fa655a3

YoriShDefaultAliasEntries[] = {
{_T("F7"), _T("history -u")},
{_T("assoc"), _T("yassoc $*$")},
{_T("cd"), _T("chdir $*$")},
{_T("cls"), _T("ycls $*$")},
{_T("copy"), _T("ycopy $*$")},
{_T("cut"), _T("ycut $*$")},
{_T("date"), _T("ydate $*$")},

Even aliases like C: resolve to chdir C:. See

yori/sh/main.c

Lines 276 to 283 in fa655a3

YoriLibSPrintf(AliasValue, _T("chdir a:"));
for (Letter = 'A'; Letter <= 'Z'; Letter++) {
AliasName[0] = Letter;
AliasValue[6] = Letter;
YoriShAddAliasLiteral(AliasName, AliasValue, TRUE);
}

Would the intention be to skip this type of initialization too?

Hi Malcolm..

  1. I'd love to help with the missing documentation.. although I might still not be 100% familiar with every feature in Yori control flow statements (like GOTO and FOR diffs in regard to CMD), but I'll try to contribute before the end of the month (I'm a bit tied up right now).

  2. I tried updating with YPM to test YORICOMPLETEWITHTRAILINGSLASH but no update is available as of yet..

  3. Knowing whether we're in interactive mode or not is a feature. I guess it depends on each shell what that actually means; but as far as I understand it, it's always ONLY about knowing whether we're running a shell to type in commands and expect outputs and responses, or if we're running a script that was called directly (from a double click, or a context menu). Nothing more. I don't think the shell should concern itself with limiting pre-defined aliases or features, as everything pre-defined should be available to both the interactive shell and to running scripts. So no, I don't think the shell should skip any of its own initialization; it's only about the USER initialization. The user selects what to do with the "IS_INTERACTIVE" information in a given Init script or in regular scripts. The most simple example would be to use an Init script to show a welcome message or QOTD for "interactive" mode and show nothing when running scripts (in "non interactive" mode). For the user, the interactive shell is started by his own action (like opening a terminal) and usually keeps running after a script has finished execution. While in non-interactive mode a script is usually passed on as argument to the shell before starting and the terminal usually closes after execution ends if nothing prevents it (like a PAUSE, SLEEP or INPUT command). An "IS_INTERACTIVE" variable would have NO impact on this, but it would only need to correctly identify how the environment started: interactive or non-interactive.

Having said that, there are probably shells that give some startup options to skip initialization stuff (like running in SAFE MODE), but that's another thing.

  1. Changes like this are in the github source tree but need more testing before they're really ready to go to everyone. After writing the comment in this issue, I realized that I forgot a case, which is when backslashes are at the end of an argument and a quote is being implicitly added, meaning those backslashes require additional escapes. This is pushed as commit e8e2893 . Trying these out is probably best done by compiling from source; there are also daily builds (see ypm -download-daily); I don't advertise this much since these builds can be very buggy.
  2. I pushed ea23dd6 to set an interactive variable when the shell is launched in a form that will prompt the user for input. This includes no arguments and /k. /c and /ss are considered non-interactive. Note that it's possible to launch a non-interactive shell from within an interactive shell; in this case, the interactive value is inherited (once interactive, always interactive.) In theory any interactive initialization has already been performed, so scripts have the option to detect prior initialization.

I just compiled with VS2019 x64 (Win10 x64) with no errors.. but I can't seem to open a shell..

Current directory:
D:\Command\Yori\Compiled

Command to be executed:
"D:\Command\Yori\Compiled\yori.exe"

ConEmuC: Root process was alive less than 10 sec, ExitCode=x80000003(2147483651).

This works (from an existing Yori prompt over the compiled dir):
$ .\yori -c .\sdir
$ .\yori -c .\ycpuinfo

This (from ConEmu) doesn't; it just just closes down (with exit code x80000003):
$ .\yori

This throws an error "argument not understood, ignored: /k":
$ .\yori /k

Am I missing something?

My best theory is that this code was compiled, changes were picked up from github, then recompiled - is this correct?

80000003 may be STATUS_BREAKPOINT indicating the code is trying to break into the debugger, and no debugger is attached. It might also be E_INVALIDARG, although Yori doesn't use HRESULTs very much, so this error would have to be coming from a different component. Running this under a debugger may provide additional information.

If this doesn't explain it, can you describe more about your build environment? The normal Yori build environment won't create directories like Compiled so I'm unclear what's happening here. I tried to replicate this using the code from master, Windows Server 2022 preview (effectively a Windows 10 feature update), and the 2022 EWDK (which includes Visual Studio 2019 16.9.2 plus the 2022 SDK), and everything worked as expected.

The output of yori /k is expected. /k means "run the specified script, and then display an interactive prompt afterwards." Here, no script is specified, so the argument makes no sense.

The path "D:\Command\Yori" is where I put Yori related stuff.. There's the "Bin/" subfolder (where Yori binaries actually are), a "History/" subfolder, and yesterday I made the "Compiled/" subfolder just to test it. Its content is simply a copy from "yori-ea23dd6242ded3142a4a76f264f5ce55d6a283a2\Bin\amd64".

I'm using MSVC 19.27.29112 for x64 on WIndows 10 21H1.

I understand what happens with the "/k" switch; I kind of inferred it was the intended behavior. I mentioned it in case it wasn't, because CMD.exe does take the /K switch alone to open the console and keep it open. Yori wouldn't need it because it already does that by default when running yori.exe. But keep in mind some people would expect that to work.

@malxau I was able to compile Yori and test your changes.. The debugger helped.

The %YORIINTERACTIVE% environment var is a nice addition and works perfectly; however, it shows a value (1) only when the shell started in interactive mode, which of course does the job. But perhaps you could consider to add a default value (0) when running in non-interactive mode, to keep consistency (and prevent future type mismatch comparisons).

I also tried the %YORIINTERACTIVE% var within a Yori script started from an interactive shell, which (as you've already mentioned) echoed as 1 (INTERACTIVE). My head is spinning a little bit here 😊 ... Because I agree with what you've described it should happen (once interactive, always interactive). But I put it to the test. CMD does it (batch files running from the prompt echo as INTERACTIVE) but Bash doesn't. Bash scripts running from the interactive shell echoed directly as NON-INTERACTIVE, while at the same time environment INIT scripts (profile, .bash_profile, .bashrc) echoed properly as INTERACTIVE for the shell and NON-INTERACTIVE for scripts. Just something I thought was worth mentioning.

I noticed YORICOMPLETEWITHTRAILINGSLASH is now disabled; completion no longer uses the trailing backslashes. I tried "CD DIR\" and still gives me a CHDIR error.. So I think is best that way for the time being. I just wasn't sure which way you'd take.

One other thing if I may ask..
Is there a way for SDIR.exe to group folders (first) and files (second)? and then have them both ordered alphabetically?..

Sorry for the delayed response.

YORICOMPLETEWITHTRAILINGSLASH should still be there and functional. Can you confirm that you have this option set without misspelling etc? The expectation after these changes is that CD DIR\ and CD "DIR\\" should both work. CD "DIR\" will be interpreted as a literal quote, not a trailing backslash. This is consistent with the Visual C++ command line parsing rules, even though it is obscure and counter-intuitive. The expectation of the changes I've been working on is that YORICOMPLETEWITHTRAILINGSLASH will do the "right thing" automatically - if quotes are needed, it will use double-backslash so as to escape the backslash without escaping the quote.

For YORIINTERACTIVE, I think the principle is that CMD executes all scripts in what bash would call "source" - the script is executed as part of the parent shell process and its side effects are visible to that process. What this means is that if a script is executed as part of an interactive shell and it would do things differently on an interactive shell, the script should observe that the shell is interactive, which in bash is not really correct since a script would typically be invoked under an interactive shell but will not have side effects in the parent process (ie., the script itself is fully non-interactive.) In a strict sense, this would also happen by executing a script with yori /c script.ys1, where the child process will terminate and have no side effects in the parent; my earlier change made no attempt to mark this as non-interactive, although it certainly could.

Good point about sdir. It might be easier to have separate issues for some of these things rather than trying to have one issue discuss all kinds of things (it's easy for things to get forgotten this way.) As of now, it looks like there's no way to do this: sdir will apply multiple sort orders but there's no -sfa since file attributes are a bitmask so the resulting sort order is probably counter intuitive. It would be possible to have a single value for directory status, which should then allow this type of sorting. The unfortunate thing is this is a one-off rather than being applicable to all file attributes, and other attributes might benefit from the same treatment (sigh.)

More updates on this...

Commit f4ba700 fixes a bug with tab completion and trailing slash

Commit 2453bdc allows sdir to sort by directory state

Commit 4d686bb defines YORIINTERACTIVE if it's not defined already

Commit 7467026, commit 1853054 and commit 9bd74ed allow an easier path to transition to a testing build without compiling it manually. This won't help until there's a new stable build that includes this support, allowing from a transition from that build to a future testing build.

I think now this issue should be closed, and if there are further items those can be discussed in their own issues.

@malxau I tested the changes and everything seems ok. Closing this issue is also on point. Thank you.

I do have some comments and/or recommendations, not necessarily issues, but if any of these notes is worth fixing please let me know and I'll open up a different issue:

  1. Consider adding up file version meta data to (at least) the yori.exe binary.

  2. Consider making %Date% and %Time% environment vars available (as with CMD). And perhaps expand functionality by allowing somehow different date and time formats. CMD uses settings in "HKCU:\Control Panel\International" to determine the date/time format. I believe having this two vars available would be enough. But if you really wanna improve functionality you could implement something like: %DATE:YYYYMMDD% %DATE:DDMMYY% %TIME:HHMMSS% and so on.. Just an idea.

  3. Having YORINTERACTIVE enabled now works but produces something like cd "Dir Name\\" when completing. It's automatically adding an escape character. I assume this is intended behavior and I'm fine with it. I mention it in case is not.

  4. Consider having case sensitivity directory names as with CMD:

(YORI)$ cd "dir name"
(YORI)$ echo %CD%
D:\Workspace\dir name

(YORI)$ cd "DIR NAME"
(YORI)$ echo %CD%
D:\Workspace\DIR NAME

Then CMD uses the correct name in any case:

(CMD)$ cd "dir name"
(CMD)$ echo %CD%
D:\Workspace\Dir Name

(CMD)$ cd "DIR NAME"
(CMD)$ echo %CD%
D:\Workspace\Dir Name

I think this qualifies as unintended behavior !?.. It also affects how the prompt shows up.

  1. Consider adding a true comment character for Yori scripting (like :: or ; or #) after which no parsing is done. I know we've already talked about this. Just thought worth mentioning it again.

  2. Consider for Yori scripting to break apart from batch. Yori is already compatible with batch scripting by calling cmd.exe and Yori scripting is already different than batch files. They're not truly compatible. I think it would give you greater freedom and boost Yori's functionality. This would allow to perhaps implement new scripting features like true functions and more practical code blocks and/or control flow statements in the future. Think of it like competing with Bash scripts, instead of Batch files.

[Edit 2021-08-24 11:27]

  1. I tried the command ypm -a amd64 -download-daily "Destination/" but the -a flag didn't seem to work !? it downloaded everything (for all architectures)..

Have a great day!

  1. I pushed a change to add version resources everywhere.
  2. Since Yori has backquotes, the intention was to use external programs rather than predefined variables. These allow far more possibilities than any hardcoded set in the shell. For this, see the 'date' command. Note it allows you to specify a format, which was done to avoid all of the locale-specific parsing that CMD scripts end up doing.
  3. Yes, the extra escapes prior to a quote are intentional and required by Visual C++'s command line parsing rules.
  4. This is a pandora's box; more below.
  5. I see your point, but note that all characters are valid for Windows commands, so this implies yet another escaping sequence.
  6. As you've already mentioned, Yori has its own scripting environment. That environment is very simplistic, mainly because it doesn't seem like a good investment to make it better: since it's not installed on every device, people writing scripts will probably prefer CMD or PowerShell over Yori no matter what happens here. Note though the intersection between this point and 2 above - it's true that a Yori specific scripting system could do more things than CMD, but every time it differs, the result is confusion for people expecting something more CMD like.
  7. The intention of download-daily et al is to obtain the entire tree for offline installation. At this point it is unknown what the final target requires - in addition to architecture, there's also debug or non-debug, symbols, source, etc. This command gets all of them.

For the pandora's box comment, the original Win32 system allowed opens by name, but no way to query names for opened objects. SetCurrentDirectory() follows this model, where a name can be specified and used, but a later call to GetCurrentDirectory() just returns the previously provided name, without adjusting for on-disk case.

In NT 3.x, CMD behaves the same way as Yori. NT 4 appears to change this by trying to perform something like GetLongPathName(), which works by querying the filesystem for each component in the path, trying to enumerate the "real" case for the component. This is obviously slow but is also unreliable: there is no guarantee that a user has access to enumerate parent directories. Further, because NTFS allows names differing only by case, performing a case-insensitive enumerate does not guarantee to resolve to the same directory.

I believe what NT 4's CMD is doing is going component-by-component, on failure preserving the user specified case, and always using the user specified case in the call to SetCurrentDirectory(). If that works, it displays the case that it found via these component enumerates. This means it needs to keep an internal concept of current directory that differs from the OS concept, as the two have different cases.

It's possible for Yori to do the same thing, but it's not trivial and will incur a runtime cost.

  1. Ok, cool!
  2. I kinda figured that.. That's why I mentioned to "consider". A few times I forgot and tried to use them.
  3. Ok! (extra quotes).
  4. I see.. Getting the path case right is not something that would break things.. But still, is very nice feature if it can be done at some point. I noticed it when I opened CMD and Yori at the same time.

2021-08-30 10 13 14_mgH

  1. Another "please consider it".. :) .. Characters like | can be used with Rem in CMD.
  2. Look.. I like CMD because is simple but it's somewhat stagnant and legacy, I think there hasn't been any important new feature since it replaced MS-DOS. And now I'm using Yori as default shell replacement because it does some things better. It adds new features. The aliases alone are a high selling point... I also love/hate PowerShell because is both "powerful" and annoying. I love Bash and other *nix shells but they're clearly not made for Windows environments, so I usually have to do some extra work. My point is.. There are many options for shell scripting, and yet, I keep using batch files for simpler tasks, but there's still something missing in there, and Yori scripting is not yet a complete option (and I agree it probably doesn't have to). I also think there should be something in between Batch and Bash. But this is just my opinion.
  3. Ok. I think the -a flag should do what it says (even for dailys), but I have no issue with this. Just mentioned it in case it was a bug.

———————————————
New question:

8. Is there a character (or way) to separate multiple commands in aliases?..
(Like $T in Doskey and ; in Bash)..

Note: I'm no longer given the option to comment and close..

Hello @malxau ..

I noticed name casing is working now in the latest daily.. 👌😀

2021-09-15 03 40 48

A small step for Yori, a great leap for replacing Cmd.. 😎