Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 7 years ago.
Improve this question
I recently switched from Linux to OSX. I use console heavily, and previously I was able to do things like
ls ./dir -sgh
cp ./file ./dir -Rf
and so on. If I missed an option, it was enough to press up and just add it. OSX forces me to put options before arguments, like this:
ls -sgh ./dir
cp -Rf ./file ./dir
This behavior is frustrating, it is easy to forget about an option and you have to navigate to the beggining of a line just to add it. It is also hard to add another option if you forget about one.
Is there an easy way to fix this behavior and make it work the linux way? I guess it involves replacing default programs like ls with some counterparts.
OS X's userland is a mash of BSD, (outdated) GNU, and Apple utilities.
If want your utilities to behave like their Linux counterparts, you should probably install the entire GNU coreutils suite with something like
Homebrew.
Once Homebrew is installed, just use it to install the coreutils:
$ brew install coreutils
Edit: I didn't have to update my $PATH personally, but YMMV.
If your shell isn't finding the Homebrew-installed coreutils, make sure /usr/local/bin (or your custom path, if Homebrew was configured as such) is before /usr/bin and /bin on $PATH.
In the best-case scenario, all programs dynamically link the system libc and use getopt to process their arguments. getopt only looks at arguments until it finds the first non-option argument, then stops. You cannot change this behavior of getopt. You would have to replace the system libc with one having a different implementation of getopt.
However, there is no guaranteed that all programs load libc dynamically; some might link statically, in which case replacing the system libc would have no effect. Others may not even use getopt. In either case, the only option is to replace the program with one that behaves the way you want.
Option processing is not a feature of the shell. You'd need to patch the argument processing logic in each individual utility.
Alternatively, you could install e.g. the corresponding GNU utilities. They are not completely option-compatible with the default *BSD utilities, so you can't replace the system binaries; but you can arrange your PATH so that the locally installed versions are preferred for your personal use. Homebrew is popular for managing this.
In Bash, ctrl-A jumps to the beginning of line, and M-n jumps past the first token.
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 2 years ago.
Improve this question
Is there some way to use alias ./ = "..." or some other command for doing this?
This is in principle a function of the shell you're talking about. Your alias syntax resembles the syntax for the alias commands of Bash and the POSIX shell, so we'll start there. I'm having trouble seeing why a conforming POSIX shell would reject
alias ./=...
to define an alias for ./, but
bash 4.4 does not accept it ("bash: alias: `./': invalid alias name"). That may be a point of non-conformance, but it is of little import because
such an alias would not have the effect I imagine you're looking for / concerned about, because aliases are recognized only where they appear as a whole (shell) words. Thus, although alias substitution might, in principle, be applied to the ./ in the command ./ ls, an alias for ./ would not be relevant to the command ./ls.
For a complementary view, consider tcsh 6.20. This is a member of the csh family of shells, so not a POSIX shell, but this family also has an alias command, and this particular shell does allow you to alias ./. Example
$ tcsh
$ alias ./ echo
$ ./ foo
foo
But in this family, too, alias substitution is applied only to whole words:
$ ./foo
./foo: Command not found.
As for alternative approaches, the other potential way for someone to try to redefine a common command in a POSIX-ish shell such as Bash would be by defining a shell function with the same name. This is not an issue for words containing the / character, however, because function names cannot contain that character. (And shells in the csh family do not provide for functions.)
But if your concern is about the effect that your code may have if run on a compromised system, then there is ultimately no assurance to be had. A sufficiently deep system compromise could replace any or all of the installed shells with customized versions, could replace the standard ELF loader with a customized version (so that compiled programs aren't safe, either), and could even replace the kernel with a customized version.
Thus, if you do not trust the system then you need to provide a whole system of your own: a bootable image with a kernel and enough tools, chosen and vetted by you, to do what you want to do. This is akin to a rescue image: it could examine the host filesystems by mounting them, but it would not run any of the programs there. This also has the advantage of testability. You don't have to try to ensure that your code does the right thing in every environment, but rather only that it does the right thing in the environment you built for it.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 2 years ago.
Improve this question
How to restrict specific commands (for example "kill") in Linux for the specific local user?
I am trying to restrict the "kill" command.
this is not possible.
(unless you patch then recompile your Linux kernel; see also kernelnewbies.org; another possibility might be to code your own Unix shell - see also chsh(1) and passwd(5) - or patch and improve an existing open source shell such as GNU bash or zsh to forbid using the kill(1) command. Be then however aware of Rice's theorem).
As documented, the kill(1) command uses the kill(2) system call. Read also of course sigaction(2), syscalls(2), signal(7) and signal-safety(7) and Advanced Linux Programming
Any advanced Linux user could download or recompile (using GCC) his equivalent of the kill(1) command (or use e.g. some interpreter like Python or Guile doing so). You might configure his/her $PATH variable (see environ(7) and exec(3)...) to make more difficult the accidental use of the kill(1) command, but there is No silver bullet since your user could run /bin/kill in his/her terminal. Read also a good operating system textbook.
Look for inspiration into the source code of existing open source software (also use strace(1) and gdb(1) to understand their dynamic behavior), such as Qt, GNU bash,
RefPerSys, FLTK, POCO, GNU make, etc and many others on github or gitlab.
So you need to design your solution in the dual way: properly implement (perhaps with signalfd(2) used with poll(2)...) a good enough signal handler.
Read also credentials(7), namespaces(7), pid_namespaces(7), capabilities(7) and consider using carefully setuid techniques in your software stack.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 7 years ago.
Improve this question
I don't want to install multiple instances of perl.
How can I upgrade my Perl to latest version or delete existing Perl installation and install a new version of Perl in Ubuntu 14.04.
After new installation, will it conflict with older installation files.
I'd do it like this:
wget http://www.cpan.org/src/5.0/perl-5.22.1.tar.gz
tar xvfz perl-5.22.1.tar.gz
cd perl-5.22.1 && ./Configure -Duseithreads -des && make && make test && make install
/usr/local/bin/cpan -u
This puts a source build of perl in /usr/local/bin
Then check your path has /usr/local/bin in it, and if you want typing perl to run your new perl, ensure it's in front of /usr/bin (this is a fairly common scenario, but I can't say for sure if that applies.
Whilst you say you don't want to install multiple perl versions - this is a bad idea.
perl is distributed as part of your operating system. Packages depend upon it, and the particular version. You cannot tell what you might break by altering versions - not least because the way perl handles certain things does change between versions (like hashes).
Messing around with /usr/bin/perl is a road to some future pain (not least - it makes an 'update' of your OS annoyingly difficult, because you can no longer use the package manager without a bit of hackery)
If you REALLY REALLY want to do that you can set -Dprefix= in your Configure options. But as a sysadmin of 15 years experience, I can tell you - no good will come of it, you will break your OS in a variety of minor, but cumulatively really annoying ways. (And maybe some bigger ways)
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 8 years ago.
Improve this question
I found both git --version and git version are okay. They will show me the same output. However, if I try some other command, say, ls -l and ls l, only the first works.
I'd like to know how the arguments work in command line. When and where the dash or double dash before flag/arguments are necessary? Or I might be wrong with some concept when using the shell.
Thanks!
This is command dependent. There are some common commands like git or tar who have optional dashes. Most do not. You really have to read the man page to see what the command expects.
There are basically two styles for providing arguments on the command line.
The GNU style is characterized by characterized by options that look like this (-v) or like this (--verbose). The single dash sets of "short" options and the double-dash sets off "long" options. Not every short option will have a corresponding long option, or vice-versa. This syntax permits short options that do not take option arguments to be combined (for example, ls -al is equivalent to ls -a -l).
In the BSD style, one can have an option that looks like this: java -version where -version a single option, which may or may not take an argument. This style has evolved into one where complex commands have many subcommands, typically referred to as "verbs." This style is used by Apple in OSX, for example launchctl unload /path/to/some.plist ("unload" is the verb).
Hopefully this information will help you read the documentation as you go. You can find the options, and what they do, for any command, by executing, for example man ls. Note that, in some cases, there is more than one manpage for a given name. In this case, you can provide the section of the manual in which you would like to do the look up, eg man 1 crontab to see how to use the program that edits users crontabs, and man 5 crontab to see the format of an entry in these tables.
Understanding these families is useful. The authors of these commands do not want to reimplement option parsing, so they use one of the common libraries for performing this task. Thus, if you encounter a new command, once you know what family it falls into, you will have an easier time understanding the manpage.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 8 years ago.
Improve this question
I am a computer science minor and I do appreciate *nix a lot more since i started to delve into computer science. I used to be a windows fan boy and now i own two macs (as well as my PC which has windows and ubuntu on it).
I want to learn more about how linux was developed. I know that linux is only the kernel and the GNU is actually the most of what i am interfacing with. So when i type ls -al on my mac which uses unix how is it different from when i type ls -al on my Ubuntu boot on my PC? Does the difference actually lie in the differences between linux and unix? Or does unix use a non-GNU libraries for stuff like ls and cd?
So what exactly are the difference of linux and unix? Does Unix use GNU libraries for ls, cd, and all those common terminal operations?
First of all, you need to know that ... Linux Is Not UniX. :)
Good question, but it's difficult to give a straight answer.
The kernel is different. The design is different. The software is different (!)
That said, if you have Mac OS X (UNIX), you can build almost any command-line tool that was written for Linux.
Most of the free open-source software is compatible with both Linux ans UNIX, so depending on your level, you might never know the difference.
But technically, there's a huge difference. If you're on a hardware and driver-level you will start noticing differences, but if you're above those levels, you can easily write portable code.
Some people would claim that Linux is the poor-man's UNIX (which is probably also true), while others would say that Linux fixes the problems that UNIX has.
Due to the nature of the question (it's fairly broad), it's difficult to go in details.
I work with both and do not feel a huge difference. My UNIX was set up for me, so I'm basically a novice user there, but I had to install and configure parts of my Linux system myself.
I would say (in my own opinion) that most of the time, Linux is something you build yourself, you decide which components you want. UNIX on the other hand is a little more "one big package", though you can still add components.
Looking at it from a different angle: Linux is open-source and free, where some versions of UNIX aren't. UNIX is often found in enterprise servers from large companies.
Take a command like 'ls' as you mentioned. Older versions of UNIX had a command called 'lc' which listed directories instead of files (as far as I recall). This command does not exist in the UNIX that Mac OS X is based upon, so there's a difference between UNIX and UNIX.
On the other hand, Linux did not make a straight copy of the UNIX command 'ls'. The output often differ slightly, and the switches are different. But!
If you're running Bash, then Bash on your Mac OS X is most likely exactly the same Bash you've got on Linux, just the version differ.
If you got 'curl' on your Mac, and 'curl' on Linux, then it IS the same tool, because it's built from the same sources; it's just built for two different Operating Systems.
GCC is the same as well. (GNU is Not Unix - but it works well on UNIX).
If you install the gitolite server (which I'm quite fond of), you will experience that it will not install on the stock Mac OS X 10.5.8; this is because the arguments for the 'cp' command differ. The author refused to correct the problem, when I suggested him a solution that would work on all platforms. So 'cp' may not always be 100% compatible, and I do not know whether or not it would be a good idea to 'upgrade', because the 'cp' that you have now is compatible with the scripts that Apple provided with your system. Upgrading 'cp' to a different version could break compatibility, which could mean that your system got corrupted and would need a re-install. -So it's better to not upgrade that particular command. ;)