6 ms·
The difference would be that you wouldn't fork processes for `cat` etc, instead treat them as builtins (like `echo` or `which`).
by LeonidasXIV 4y ago
The difference would be that you wouldn't fork processes for `cat` etc, instead treat them as builtins (like `echo` or `which`).
- chrisjc 4y agoI use Linux with ignorance. But how do you know what is part of the shell vs whatever `cat` is (system/kernel function)? macOS (prob diff from Linux obviously since based on BSD): $which echo /bin/echo $ which cat /bin/cat $ which which /usr/bin/which It's these kinds of threads that I learn so much.
- jasomill 4y agowhich is not a bash builtin (on Mac or Linux); use type instead: $ type echo echo is a shell builtin $ type cat cat is /bin/cat $ type which which is /usr/bin/which $ alias a=true $ type a a is aliased to `true' $ function f { true; } $ type f f is a function f () { true } Incidentally, zsh, the current default Mac shell, has both type and which as internal commands, with different output: % which echo echo: shell built-in command % type echo echo is a shell builtin % which cat /bin/cat % type cat cat is /bin/cat % which which which: shell built-in command % type which which is a shell builtin % alias a=true % which a a: aliased to true % type a a is an alias for true % function f { true; } % which f f () { true } % type f f is a shell function Note that, on zsh, the "native" command is actually whence; which and type are equivalent to "whence -c" and "whence -v", where % man -W zshbuiltins \ | xargs groff -Tutf8 -mandoc -P -cbdu \ | awk ' /^ [^ ]/ { out = 0 } /^ whence / { out = 1 } { if (out) print } ' whence [ -vcwfpamsS ] [ -x num ] name ... For each name, indicate how it would be interpreted if used as a command name. If name is not an alias, built-in command, external command, shell function, hashed command, or a reserved word, the exit status shall be non-zero, and -- if -v, -c, or -w was passed -- a message will be written to standard output. (This is differ‐ ent from other shells that write that message to standard er‐ ror.) whence is most useful when name is only the last path component of a command, i.e. does not include a `/'; in particular, pat‐ tern matching only succeeds if just the non-directory component of the command is passed. -v Produce a more verbose report. -c Print the results in a csh-like format. This takes precedence over -v. -w For each name, print `name: word' where word is one of alias, builtin, command, function, hashed, reserved or none, according as name corresponds to an alias, a built-in command, an external command, a shell function, a command defined with the hash builtin, a reserved word, or is not recognised. This takes precedence over -v and -c. -f Causes the contents of a shell function to be displayed, which would otherwise not happen unless the -c flag were used. -p Do a path search for name even if it is an alias, re‐ served word, shell function or builtin. -a Do a search for all occurrences of name throughout the command path. Normally only the first occurrence is printed. -m The arguments are taken as patterns (pattern characters should be quoted), and the information is displayed for each command matching one of these patterns. -s If a pathname contains symlinks, print the symlink-free pathname as well. -S As -s, but if the pathname had to be resolved by follow‐ ing multiple symlinks, the intermediate steps are printed, too. The symlink resolved at each step might be anywhere in the path. -x num Expand tabs when outputting shell functions using the -c option. This has the same effect as the -x option to the functions builtin. Finally, note that the bash type command also has many options, $ info bash -n 'Bash Builtins' \ > | awk " > /^'/ { out = 0 } > /^'type'/ { out = 1 } > { if (out) print } > " 'type' type [-afptP] [NAME ...] For each NAME, indicate how it would be interpreted if used as a command name. If the '-t' option is used, 'type' prints a single word which is one of 'alias', 'function', 'builtin', 'file' or 'keyword', if NAME is an alias, shell function, shell builtin, disk file, or shell reserved word, respectively. If the NAME is not found, then nothing is printed, and 'type' returns a failure status. If the '-p' option is used, 'type' either returns the name of the disk file that would be executed, or nothing if '-t' would not return 'file'. The '-P' option forces a path search for each NAME, even if '-t' would not return 'file'. If a command is hashed, '-p' and '-P' print the hashed value, which is not necessarily the file that appears first in '$PATH'. If the '-a' option is used, 'type' returns all of the places that contain an executable named FILE. This includes aliases and functions, if and only if the '-p' option is not also used. If the '-f' option is used, 'type' does not attempt to find shell functions, as with the 'command' builtin. The return status is zero if all of the NAMEs are found, non-zero if any are not found.
- dmurray 4y agoWhat's the advantage? Forking processes is more heavyweight than a typical function call, but that's hardly a concern if the use case is a REPL.
- unixgoddess 4y agoit's not just about forking processes. Instead than a single binary that needs to satisfy as much use cases as possible while remaining small and general, you would have a lot of more atomic functions that users can mix and swap as needed case-by-case.
- lelanthran 4y ago> Instead than a single binary that needs to satisfy as much use cases as possible while remaining small and general, you would have a lot of more atomic functions that users can mix and swap as needed case-by-case. Maybe I'm missing something here (it's been a long time since I last looked at the busybox code), but isn't busybox a single file that has a lot of atomic functions that callers can mix and swap as needed, using the shell as a REPL? IIRC, and please correct me if I am wrong), all those little functions in busybox are simply single functions. There's a `cat` function, and a `head` function, and a `cp` function, etc. I don't see what can be gained by moving them into a library file, and using the shell to call those functions, instead of leaving them in the shell program and calling them.
- lelanthran 4y ago> What's the advantage? Forking processes is more heavyweight than a typical function call, but that's hardly a concern if the use case is a REPL. I was wondering the same thing, to be honest - if you're in a REPL, does it matter that it takes 200ms to "call" a function than if it takes 20ms?
- jgerrish 4y agoSometimes, hitting those roadblocks leads to a better solution. Maybe the new model is slower, and somebody looks into it, and realizes if they add a caching layer between the "REPL" module and the kernel ioctl, or service orwhatever, it will speed things up. I run find and grep lot. And I'm sure the kernel caches a lot of the FS stuff, but there are higher-level things that could be cached and shared with other "REPL" modules. Like predictive URL middleware in browsers. Pluggable middleware that can be enabled or disabled. Available now on the OS module store: Larry's Grep Count Document Prefetch Module. Certified Safe by BlahCorp. This isn't a new idea, and I'm sure others have had it before me.
- deadly_syn 4y agoEcho is a builtin in bash. https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html#index-echo https://www.gnu.org/software/bash/manual/html_node/Bash-Buil...
- kasabali 4y agoBusybox can do that: https://unix.stackexchange.com/a/274322 https://unix.stackexchange.com/a/274322
- nibbleshifter 4y agoI wish I'd known this a few years ago, when I wrote a fucking disgusting wrapper for busybox to do basically the same thing. Maybe I'll revisit that project.