To: Rob Hagemans , Chief Programmer PC_BASIC Project
From: a user Mark Coffman
RE: PC-Basic Shell Command. Bug Report
Date: July 9,2016
I have found several bugs in Windows 10 (64) PC-Basic version 15.08.9 that affects
the basic "shell" command that appears to be fairly easy to fix. I've got to have the
shell command functionality to speed up things like in memory file sorts and file copy
and to post-analyse returned response files. The Windows (32) cmd shell runs in both
32 and 64bit windows, and is very fast and has commands very similar to the original
DOS based shell commands in the historic programs.
PC-BASIC Shell Command
I believe the shell documentation says the shell enablement statement on the
pc-basic run time command line has three parts; --shell=none --shell=native or --shell=command
(*) bug #1 - I believe the documentation could read to be more clear;
pc-basic run time command line has three parts; --shell=none --shell=native or --shell=literal_command
So for example we can say; pcbasic --shell=dir or pbasic --shell=echo and it is taken as valid. Ok.
Lets start as run in the 32bit windows cmd.exe shell; pcbasic --shell=dir
basic come up and we type; shell and basic returns after printing the directory output, the dir command
entered into the shell. Ok. Now lets start basic again using the command line; pcbasic --shell=echo
basic comes up and we type; shell basic returns with the message 'ECHO is ON.' Ok.
then let's type; S$="123" : SHELL S$ what should now come back is the windows command shell
executing the command echo 123 which means that a string 123 should be returned and printed.
(*) bug #2 & #3 - the bug is when the string returned it actually reads; /C \"123\"
there are actually two bugs here; #2-^^ ^^^^^^-#3
I believe bug #2 the first two characters may be a; ^C , a control C, remaining in the ouput buffer pipe
that may have been sent there to get the cmd shells attention. It should not be represented in this output.
This is only an educated guess. I believe bug #3 is that the shell input string is surrounded by two illegal
characters \" on the begining and at the ending of the string. So the cmd shell sees the incorect command
echo \"123"\ If you need two do two different things in Linux and Windows shells you could change the
--shell=native syntax to --shell=windows or --shell=linux, if necessary.
Recovering shell command functionality in PC-BASIC as it exists
Ok. let's test this to make sure we really understand it. The command line start up; pcbasic --shell=native
In this case if we say; shell and basic takes us into the command shell and we need type an exit command
to get back to pc-basic - Ok. this is correct behavior. But now lets see if we can defeat the bug of the special
\" characters in the passed string, regaining some utility of the shell command in pc-basic despite the errors
at the cost of a bunch of special basic code. I happen have an executable program "a" in the directory
"\mingw\bin\" that prints Hello World! We now enter the pc-basic program:
pcbasic --shell=native
100 REM CHR$(34) = "
110 S$="mingw"+chr$(34)+"\bin\a "
120 SHELL S$
130 STOP
RUN
We get the Hello World! printout from test.c execution running, because we have given the cmd shell the trick
command; \"mingw"\bin\a \" the command shell then ignores the trailing special characters \" This will allow
us to write the shell command we actually want to execute into a batch text file bat.bat, that is in my C:\commons\
subdirectory then execute a pc-basic shell string; 100 SHELL "commons"+chr$(34)+"\bat " to run the freshly
minted batch file from within existing pc-basic PROGRAM.
Thank you for your great BASIC package.
Signature
Sincerely; Mark Coffman
email: mscoffman@yahoo.com
{eot}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The double quotes are indeed a bug as they prevent the command to be run - this has already been fixed in the development version and will also be fixed in the next stable release. Thanks for reporting this!
Using things like --shell=echo is not (and won't be) supported. The command must be a 'shell command' - a terminal emulator such as sh or bash on Unix or CMD.EXE on Windows. With such commands it works as expected, as long as they follow the syntax of the operating system's primary shell. The documentation reflects this by saying that --shell=command uses a custom shell run with command.
In practice (on Windows) the command SHELL A$ calls CMD.EXE /C A$. The /C is part of the syntax of CMD.EXE and not a bug.
To be perfectly honest, the SHELL command is a bit of a mess - it's not at all portable since it depends on the operating system's shell. Even Windows's CMD.EXE is quite different from the DOS COMMAND.COM shell that GW-BASIC would use. There are certain fundamental limitations which are basically impossible to fix cleanly; for example, under Windows and Linux it's not possible to change the environment variables of the parent process, as can be done when GW-BASIC shells into DOS. Therefore a command like SHELL "A:" does not have the expected effect to change the current drive to A:.
The Windows drive letters also do not necessarily match the devices BASIC addresses under the same letter. That's intentional - it wouldn't be portable; moreover, for security reasons I do not want to expose people's file systems to the emulator without their explicit request.
I'm actually considering to rewrite the whole code supporting the SHELL command in an upcoming version so as to implement a (very limited) DOS emulation by default. --shell=command will probably remain supported in some way or other but --shell=native will not (it is unpredictable and not portable; something like --shell=CMD.EXE would achieve the same thing and more clearly indicates that it only works on Windows). When this is done I will update the documentation to reflect the new workings.
Frankly, the best approach for now is not at all to rely on SHELL, which is why it is currently disabled by default.
Rob
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Rob. Just to inform that we tested the functionality with --shell=cmd.exe in the launcher, and it work well for us in the brewer program, (which has a lot of routines that uses shell commands for copiyng and moving daily measurement files). Of course the pc units have to match with the mounted drives in pcbasic to make it work.
As a question, what pcbasic do when a copy action ask if you agree to overwrite an existing file?. is pcbasic forcing not to ask for answer by default? (the same as the cmd.exe copy /Y option?)
Regards.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi, not sure f I understand your question correctly but it's not PC-BASIC which determines how this works. When you use the shell you give commands directly to cmd.exe; how it interprets the copy command depends on your version of cmd.exe. PC-BASIC itself has no file copying functionality.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
View and moderate all "[CLOSED] Bug reports" comments posted by this user
Mark all as spam, and block user from posting to "Discussion"
To: Rob Hagemans , Chief Programmer PC_BASIC Project
From: a user Mark Coffman
RE: PC-Basic Shell Command. Bug Report
Date: July 9,2016
I have found several bugs in Windows 10 (64) PC-Basic version 15.08.9 that affects
the basic "shell" command that appears to be fairly easy to fix. I've got to have the
shell command functionality to speed up things like in memory file sorts and file copy
and to post-analyse returned response files. The Windows (32) cmd shell runs in both
32 and 64bit windows, and is very fast and has commands very similar to the original
DOS based shell commands in the historic programs.
PC-BASIC Shell Command
I believe the shell documentation says the shell enablement statement on the
pc-basic run time command line has three parts; --shell=none --shell=native or --shell=command
(*) bug #1 - I believe the documentation could read to be more clear;
pc-basic run time command line has three parts; --shell=none --shell=native or --shell=literal_command
So for example we can say; pcbasic --shell=dir or pbasic --shell=echo and it is taken as valid. Ok.
Lets start as run in the 32bit windows cmd.exe shell; pcbasic --shell=dir
basic come up and we type; shell and basic returns after printing the directory output, the dir command
entered into the shell. Ok. Now lets start basic again using the command line; pcbasic --shell=echo
basic comes up and we type; shell basic returns with the message 'ECHO is ON.' Ok.
then let's type; S$="123" : SHELL S$ what should now come back is the windows command shell
executing the command echo 123 which means that a string 123 should be returned and printed.
(*) bug #2 & #3 - the bug is when the string returned it actually reads; /C \"123\"
there are actually two bugs here; #2-^^ ^^^^^^-#3
I believe bug #2 the first two characters may be a; ^C , a control C, remaining in the ouput buffer pipe
that may have been sent there to get the cmd shells attention. It should not be represented in this output.
This is only an educated guess. I believe bug #3 is that the shell input string is surrounded by two illegal
characters \" on the begining and at the ending of the string. So the cmd shell sees the incorect command
echo \"123"\ If you need two do two different things in Linux and Windows shells you could change the
--shell=native syntax to --shell=windows or --shell=linux, if necessary.
Recovering shell command functionality in PC-BASIC as it exists
Ok. let's test this to make sure we really understand it. The command line start up; pcbasic --shell=native
In this case if we say; shell and basic takes us into the command shell and we need type an exit command
to get back to pc-basic - Ok. this is correct behavior. But now lets see if we can defeat the bug of the special
\" characters in the passed string, regaining some utility of the shell command in pc-basic despite the errors
at the cost of a bunch of special basic code. I happen have an executable program "a" in the directory
"\mingw\bin\" that prints Hello World! We now enter the pc-basic program:
pcbasic --shell=native
100 REM CHR$(34) = "
110 S$="mingw"+chr$(34)+"\bin\a "
120 SHELL S$
130 STOP
RUN
We get the Hello World! printout from test.c execution running, because we have given the cmd shell the trick
command; \"mingw"\bin\a \" the command shell then ignores the trailing special characters \" This will allow
us to write the shell command we actually want to execute into a batch text file bat.bat, that is in my C:\commons\ subdirectory then execute a pc-basic shell string; 100 SHELL "commons"+chr$(34)+"\bat " to run the freshly
minted batch file from within existing pc-basic PROGRAM.
Thank you for your great BASIC package.
Signature
Sincerely; Mark Coffman
email: mscoffman@yahoo.com
{eot}
Hi Mark,
The double quotes are indeed a bug as they prevent the command to be run - this has already been fixed in the development version and will also be fixed in the next stable release. Thanks for reporting this!
Using things like
--shell=echo
is not (and won't be) supported. The command must be a 'shell command' - a terminal emulator such assh
orbash
on Unix orCMD.EXE
on Windows. With such commands it works as expected, as long as they follow the syntax of the operating system's primary shell. The documentation reflects this by saying that--shell=command
uses a custom shell run withcommand
.In practice (on Windows) the command
SHELL A$
callsCMD.EXE /C A$
. The/C
is part of the syntax ofCMD.EXE
and not a bug.To be perfectly honest, the
SHELL
command is a bit of a mess - it's not at all portable since it depends on the operating system's shell. Even Windows'sCMD.EXE
is quite different from the DOSCOMMAND.COM
shell that GW-BASIC would use. There are certain fundamental limitations which are basically impossible to fix cleanly; for example, under Windows and Linux it's not possible to change the environment variables of the parent process, as can be done when GW-BASIC shells into DOS. Therefore a command likeSHELL "A:"
does not have the expected effect to change the current drive toA:
.The Windows drive letters also do not necessarily match the devices BASIC addresses under the same letter. That's intentional - it wouldn't be portable; moreover, for security reasons I do not want to expose people's file systems to the emulator without their explicit request.
I'm actually considering to rewrite the whole code supporting the
SHELL
command in an upcoming version so as to implement a (very limited) DOS emulation by default.--shell=command
will probably remain supported in some way or other but--shell=native
will not (it is unpredictable and not portable; something like--shell=CMD.EXE
would achieve the same thing and more clearly indicates that it only works on Windows). When this is done I will update the documentation to reflect the new workings.Frankly, the best approach for now is not at all to rely on
SHELL
, which is why it is currently disabled by default.Rob
View and moderate all "[CLOSED] Bug reports" comments posted by this user
Mark all as spam, and block user from posting to "Discussion"
Hi Rob. Just to inform that we tested the functionality with --shell=cmd.exe in the launcher, and it work well for us in the brewer program, (which has a lot of routines that uses shell commands for copiyng and moving daily measurement files). Of course the pc units have to match with the mounted drives in pcbasic to make it work.
As a question, what pcbasic do when a copy action ask if you agree to overwrite an existing file?. is pcbasic forcing not to ask for answer by default? (the same as the cmd.exe copy /Y option?)
Regards.
Hi, not sure f I understand your question correctly but it's not PC-BASIC which determines how this works. When you use the shell you give commands directly to
cmd.exe
; how it interprets thecopy
command depends on your version ofcmd.exe
. PC-BASIC itself has no file copying functionality.