How can I get the output of ls - minix

How can I get the output of ls? I want to add a indirection operator =>, and it's function is same as >, it means in the command line $ls => Files, the list of files in the directory is stored in the file Files

Output redirection (and all other redirection for that matter) is a facility provided by the shell, not by the ls program. The ls just writes its output to standard output and, if the shell has redirected that to a file, that's where it goes.
So, if you want to add a => token, it's the shell that you're going to have to modify, recompile and install. That's not necessarily an easy task, I've made changes to bash in the past and, while it's relatively easy to tinker around the edges (I added an internal command for outputting the PS1 result string), I suspect redirection may be a little more difficult.
Still, it may be a matter of simply creating a new token => and copying the code that's currently executed for >. It may also be that ash, the Minix3 shell, is a lot cleaner than bash. My advice would be to investigate ash, specifically the version found in Minix3, and just have a play.

Related

post-build event with multiple if/copy combinations only execute if first file does not exist

Given the bin\ directory inside the Delphi project contains the files Cert.pem and Key.pem, the below Delphi post-build event only copies both files if C:\Binaries\Cert.pem does not exist:
if not exist $(OUTPUTDIR)Cert.pem (copy bin\Cert.pem $(OUTPUTDIR))
if not exist $(OUTPUTDIR)Key.pem (copy bin\Key.pem $(OUTPUTDIR))
As soon as C:\Binaries\Cert.pem exists, the Key.pem file is never copied.
How can I solve this in the post-build event?
Edit: unlike my 2014 post, this is indeed possible using parentheses. See my answer below.
The problem with Delphi post-build events is that they are not batch files.
It means that statements that look like lines are being concatenated by the Delphi IDE into one big & ampersand separated statement. This ensures the commands are executed in sequence, as per Command Redirection, Pipes - Windows CMD - SS64.com:
commandA & commandB Run commandA and then run commandB
So this is the actual statement that gets executed:
if not exist $(OUTPUTDIR)Cert.pem (copy bin\Cert.pem $(OUTPUTDIR))&if not exist $(OUTPUTDIR)Key.pem (copy bin\Key.pem $(OUTPUTDIR))
The problem here is that now the second if is seen as a continuation of the "then" part of the first if statement: the second if never executes when the $(OUTPUTDIR)Cert.pem exists.
What helps is a little known feature that you can wrap each command inside parentheses. Normally this is to allow one command to span multiple lines (especially for if, and for..do loops), but it also works on one line.
Wrapping each line having an if statement inside parentheses ensures they become standalone statements not affecting the other lines, even if they are being concatenated with & ampersand separators.
In the dialog it looks like this:
(if not exist $(OUTPUTDIR)Cert.pem (copy bin\Cert.pem $(OUTPUTDIR)))
(if not exist $(OUTPUTDIR)Key.pem (copy bin\Key.pem $(OUTPUTDIR)))
That way, the IDE translates it into one statement:
(if not exist $(OUTPUTDIR)Cert.pem (copy bin\Cert.pem $(OUTPUTDIR)))&(if not exist $(OUTPUTDIR)Key.pem (copy bin\Key.pem $(OUTPUTDIR)))
Now it works as intended:
When $(OUTPUTDIR)Cert.pem exists but $(OUTPUTDIR)Key.pem does not, only $(OUTPUTDIR)Cert.pem is copied
When $(OUTPUTDIR)Cert.pem does exists but $(OUTPUTDIR)Key.pem does, only $(OUTPUTDIR)Key.pem is copied
when neither exist, both are copied
when both exist, neither are copied
I did not know this "trick" when writing my 2014 post Delphi prebuild/prelink/postbuild events, so I need to write an update for it.
Searching for batch file parentheses site:microsoft.com -site:social.technet.microsoft.com -site:answers.microsoft.com did not reveal it in the official documentation, but I am not surprised as it grew hysterically, instead of being designed. Or like the Old New Thing attributes h2g2:
Much like the universe, if anyone ever does fully come to understand Batch then the language will instantly be replaced by an infinitely weirder and more complex version of itself. This has obviously happened at least once before ;)
The best documentation I could find was at Parenthesis/Brackets - Windows CMD - SS64.com:
Parenthesis can be used to split commands across multiple lines. This can make code more readable. Variables will be evaluated for the code block just as if the command was a single line.
(command)
(
command
command )
Things that break inside parenthesis
The CMD shell does not use any great intelligence when evaluating parenthesis, so for example the command below will fail:
IF EXIST MyFile.txt (ECHO Some(more)Potatoes)
...
Use multiple build events instead of putting both commands in the same event.
Executing the source lines of a build event.
I can cut this short very easily: build events are not batch files.
What happens is that all lines in your build event are concatenated together using ampersand (&) signs which are used to execute multiple commands on one command line.
This means that all the fancy control structures (if statements, setlocal, for loops) are not possible inside build events.
ref: Pasted from a blog post: Delphi prebuild/prelink/postbuild events written by Jeroen W. Pluimers
Makes me wonder why you asked since it looks like you wrote the answer in 2014. :)

Is it possible to get $pwd value from Bazel .bzl rule?

I am trying to get a value of the full current directory path from within .bzl rule. I have tried following:
ctx.host_configuration.default_shell_env.PATH returns "/Users/[user_name]/.rbenv/shims:/usr/local/bin:/usr/bin:/bin:...
ctx.bin_dir.path returns bazel-out/local-fastbuild/bin
pwd = ctx.expand_make_variables("cmd", "$$PWD", {}) returns string $PWD - I don't think this rule is helpful for me, but may be just using it wrong.
What I need is the directory under which the cmd that runs Bazel .bzl rule is running. For example: /Users/[user_name]/git/workspace/path/to/bazel/rule.bzl or at least first part of the path prior to the WORKSPACE directory.
I can't use pwd because I need this value before I call ctx.actions.run_shell()
Are there no attributes in Bazel configurations that hold this value?
The goal is to have hermetic builds, so you shouldn't depend on the absolute path.
Feel free to use pwd inside the command of ctx.actions.run_shell() (for reproducible builds, be careful, avoid putting the absolute path in the generated files).
Edit.
Technically, there are some workarounds. For example, you can pass the path via the --define flag:
bazel build :all --define=path=$(pwd)
Then the value will be available using ctx.var["path"].
Based on your comment below, you want the path to declare an output. Let me repeat: You shouldn't use an absolute path to declare the output file. Declare an output in your package. Then ask the tool you call to use that output.
For example, when you call gcc, you can use -o to specify the output. When a tool writes to stdout, use the shell to redirect it. If the tool is really not flexible, you may want to wrap it with your own script (e.g. call the tool and copy the output file).
Using an absolute path here is not the right solution. For example, it should be possible to execute the action on a remote machine (where your absolute path won't make sense.
Zip may be a reasonable solution. It's useful when you cannot know in advance the number or the names of the output files.

Oneliner to load Lua script from online (Gist) and run in current context

I have a lua REPL, and would like to run a lua script file stored as plain text at HTTPS://URL. I understand os.execute() can run OS commands so we can use curl etc. to grab the script then load(). Is that something possible to do in lua REPL with a single line?
Note: If you're going to run source code directly from the web, use https at least, to avoid easy MitM attacks.
To give this question an answer, since Egor will probably not post it as such:
(loadstring or load)(io.popen("wget -qO- https://i.imgur.com/91HtaFp.gif"):read"*a")()
For why this prints Hello world:
loadstring or load is to be compatible with different Lua versions, as the functions loadstring and load were merged at some point (5.2 I believe). io.popen executes its first argument in the shell and returns a file pointer to its stdout.
The "gif" from Egor is not really a GIF (open this in your browser: view-source:https://i.imgur.com/91HtaFp.gif) but a plain text file that contains this text:
GIF89a=GIF89a
print'Hello world'
Basically a GIF starts with GIF89a and the =GIF89a afterwards is just to produce valid Lua, meaning you don't have to use imgur or gifs, you can just as well use raw gists or github.
Now, it's rather unlikely that os.execute is available in a sandbox when io.popen is not, but if it is, you can achieve a one-liner (though drastically longer) using os.execute and temporary files
Lets first write this out because in a single line it will be a bit complex:
(function(u,f)
-- get a temp file name, Windows prefixes those with a \, so remove that
f=f or os.tmpname():gsub('^\\','')
-- run curl, make it output into our temp file
os.execute(('curl -s "%s" -o "%s"'):format(u,f))
-- load/run temp file
loadfile(f)()
os.remove(f)
end)("https://i.imgur.com/91HtaFp.gif");
And you can easily condense that into a single line by removing comments, tabs and newlines:
(function(u,f)f=f or os.tmpname():gsub('^\\','')os.execute(('curl -s "%s" -o "%s"'):format(u,f))loadfile(f)()os.remove(f)end)("https://i.imgur.com/91HtaFp.gif");

Why won't applications in Program Files run using os.execute in lua?

I'm trying to run an executable using Lua's os.execute() function. If I do something like the following it does not work:
os.execute("C:\\\Program Files\\\Movie Maker\\\moviemk.exe")
However, if I put my lua file in the same path that moviemk.exe is in then it can call it.
Any ideas why this may be?
P.S. I'm using Windows XP SP3
This is a classic problem with the command shell. It isn't really a Windows specific problem, except that on *nix, people never really got into the habit of putting spaces in file names, and Windows puts spaces in several default system places such as C:\Program Files.
What is happening is that os.execute(str) is implemented in terms of the ANSI C function system(str), which on Windows tries to duplicate the effect of typing "cmd /C "..str to the command prompt. (On *nix, it uses /bin/sh -c instead of cmd /C.)
The classic problem is that this has to split the complete command string at whitespace to decide what program to run, and what its arguments are.
Your original example: os.execute("C:\\Program Files\\Movie Maker\\moviemk.exe") effectively became cmd /c c:\program files\movie maker\moviemk.exe, which after splitting it up on whitespace, CMD tried to find a program named c:\program to execute with arguments named files\movie and maker\moviemk.exe. This isn't what you intended.
The solution is to be much more defensive about quoting.
I would write this as:
os.execute [["C:\Program Files\Movie Maker\Moviemk.exe"]]
If there were additional command line arguments to be supplied, I would use double-quotes around each, and a single space between arguments. Using the long string syntax [[...]] has the advantage that backslash isn't a special character, so you don't need extra leaning toothpicks making it harder to read the string literal.
Using double quotes around each argument should work on both Windows and *nix, although it is harder to find commands that are the same on both platforms, of course.
One other detail to be aware of is that \Programs Files might not be on C:. There might not even be a disk named C:. (My work PC boots from E: and I find more buggy programs that way.) The easiest way to learn the correct pathname is to just use the environment variable ProgramFiles. There are many other ways.
Try:
os.execute("C:\\Program Files\\Movie Maker\\moviemk.exe")
or:
os.execute("C:/Program Files/Movie Maker/moviemk.exe")
The '\' character is used for escape characters in Lua.

ack misses results (vs. grep)

I'm sure I'm misunderstanding something about ack's file/directory ignore defaults, but perhaps somebody could shed some light on this for me:
mbuck$ grep logout -R app/views/
Binary file app/views/shared/._header.html.erb.bak.swp matches
Binary file app/views/shared/._header.html.erb.swp matches
app/views/shared/_header.html.erb.bak: <%= link_to logout_text, logout_path, { :title => logout_text, :class => 'login-menuitem' } %>
mbuck$ ack logout app/views/
mbuck$
Whereas...
mbuck$ ack -u logout app/views/
Binary file app/views/shared/._header.html.erb.bak.swp matches
Binary file app/views/shared/._header.html.erb.swp matches
app/views/shared/_header.html.erb.bak
98:<%= link_to logout_text, logout_path, { :title => logout_text, :class => 'login-menuitem' } %>
Simply calling ack without options can't find the result within a .bak file, but calling with the --unrestricted option can find the result. As far as I can tell, though, ack does not ignore .bak files by default.
UPDATE
Thanks to the helpful comments below, here are the new contents of my ~/.ackrc:
--type-add=ruby=.haml,.rake
--type-add=css=.less
ack is peculiar in that it doesn't have a blacklist of file types to ignore, but rather a whitelist of file types that it will search in.
To quote from the man page:
With no file selections, ack-grep only searches files of types that it recognizes. If you have a file called foo.wango, and ack-grep doesn't know what a .wango file is, ack-grep won't search it.
(Note that I'm using Ubuntu where the binary is called ack-grep due to a naming conflict)
ack --help-types will show a list of types your ack installation supports.
If you are ever confused about what files ack will be searching, simply add the -f option. It will list all the files that it finds to be searchable.
ack --man states:
If you want ack to search every file,
even ones that it always ignores like
coredumps and backup files, use the
"−u" switch.
and
Why does ack ignore unknown files by
default? ack is designed by a
programmer, for programmers, for
searching large trees of code. Most
codebases have a lot files in them
which aren’t source files (like
compiled object files, source control
metadata, etc), and grep wastes a lot
of time searching through all of those
as well and returning matches from
those files.
That’s why ack’s behavior of not
searching things it doesn’t recognize
is one of its greatest strengths: the
speed you get from only searching the
things that you want to be looking at.
EDIT: Also if you look at the source code, bak files are ignored.
Instead of wrestling with ack, you could just use plain old grep, from 1973. Because it uses explicitly blacklisted files, instead of whitelisted filetypes, it never omits correct results, ever. Given a couple of lines of config (which I created in my home directory 'dotfiles' repo back in the 1990s), grep actually matches or surpasses many of ack's claimed advantages - in particular, speed: When searching the same set of files, grep is faster than ack.
The grep config that makes me happy looks like this, in my .bashrc:
# Custom 'grep' behaviour
# Search recursively
# Ignore binary files
# Output in pretty colors
# Exclude a bunch of files and directories by name
# (this both prevents false positives, and speeds it up)
function grp {
grep -rI --color --exclude-dir=node_modules --exclude-dir=\.bzr --exclude-dir=\.git --exclude-dir=\.hg --exclude-dir=\.svn --exclude-dir=build --exclude-dir=dist --exclude-dir=.tox --exclude=tags "$#"
}
function grpy {
grp --include=*.py "$#"
}
The exact list of files and directories to ignore will probably differ for you: I'm mostly a Python dev and these settings work for me.
It's also easy to add sub-customisations, as I show for my 'grpy', that I use to grep Python source.
Defining bash functions like this is preferable to setting GREP_OPTIONS, which will cause ALL executions of grep from your login shell to behave differently, including those invoked by programs you have run. Those programs will probably barf on the unexpectedly different behaviour of grep.
My new functions, 'grp' and 'grpy', deliberately don't shadow 'grep', so that I can still use the original behaviour any time I need that.

Resources