Is there a way to add your application path to a user's .bash_profile path variable using shell script? Also, what if the user was using a different shell like zsh etc? Is it possible to "universally" add your application path to the user's shell PATH?
Different shells have different syntaxes so there's no real "standard" way.
There are a couple of things you can do.
Install your application confirming to the FHS so that the default paths work. This means that your executables will be (alteast symlinked) in /usr/bin etc.
At the end of your installation routine, spit out a few shells snippets that the user can stick into their shell initialisation scripts so that they can use your application. You can also take this a level further and test the users SHELL variable and insert the appropriate snippet into the correct initialisation file. This might be unwise though. I don't like programs modifying my personal init files. You can support the csh "family" and the bash "family". That should cover most of the cases. People who use more obscure shells will most probably be knowledgeable enough to port the PATH settings anyway.
Related
I need to setup these two paths in my bash_profile
export AIRFLOW_HOME=pwd/airflow
and
export AIRFLOW_HOME=pwd/airflow_2
for the same server so that two different versions of airflow can coexist. Is this possible?
Can't think of any solution.. any suggestions will of great help.
Every environment variable must, by definition, be unique and non-ambiguous.
Either the software itself, or the script wrapping the software, could work with another environment variable (i.e. AIRFLOW_HOME_OPTS) which could be assigned the following value
AIRFLOW_HOME_OPTS="pwd/airflow:pwd/airflow_2"
which the wrapper could then parse depending on command line options, i.e. --default/--v2 .
Assuming this is an installation dedicated to a single user, you could also have the libraries installed in each of
pwd/airflow_1
pwd/airflow_2
and, again via wrapper option, create a symlink on the fly to whichever is the one you wish to use at the time the command executes, and removes that when the program ends.
Let's say I have a bunch of conda virtual envs and a much larger bunch of python projects.
Most of the time I reuse the same conda virtual env for multiple projects, because the environments are relatively widely scoped (e.g.: one for Spark, one for deep learning, one for data exploration, etc...).
When inside the directory of a project, I would like to be able to run conda activate and have the virtual env that I used to work on that project to automatically activate, without having to specify which one.
The reason for this is that with dozens of different projects, sometimes I forget which env belongs to which specific one.
I know that I can create the virtual environment inside the project directory, but it's a non solution for me, as I would end up having multiple clones of the same environment everywhere in my system, which is pretty redundant.
Any idea besides having a readme.MD that says "Activate THIS specific env" ?
It kind of depends on the nature of your projects and how you interact with them. For example, IDE's, like PyCharm, let you set an interpreter on a per project basis, which sounds like exactly what you want. For those working in Jupyter, each notebook stores the kernel information, but I don't know of a way to set a default kernel within a folder such that every notebook file opens to that.
As for the BASH script suggestion, that should work with a simple script like
activate_conda_env.sh
conda activate envname
but note that one has to source it in the current shell
source activate_conda_env.sh
for it to work as intended. Otherwise, doing bash -l activate_conda_env.sh would simply launch a subprocess, run the activate in there, and then exit the subprocess, having no effect on the current shell process.
Admittedly, this isn't very automated. However, one can set up scripts to run whenever a particular pattern of directory is entered, some tricks for which can be found in this thread.
In order to run UNIX programs from my current directory, I included this in my ~/.profile (I'm using Mac OS 10.9):
export PATH="./:$PATH"
Anything wrong with this approach? It seems obvious, so why isn't it included by default? And, is there any better way to do it?
Don't do it.
Adding . to $PATH is a security risk, that's why it's not like that by default. Consider the paths listed in $PATH as "trusted locations". You can run the programs and scripts in them without typing their absolute paths.
If you add . to $PATH, then you may run things by accident. For example I often run the netstat command to check statistics. I'm so used to it, I type only until "nets" and press tab, and I know it will be auto-completed to "netstat" so I very quickly press enter. If I had . on my $PATH, and there was a malicious script named "netst" in the current directory, then I might accidentally run it when I mean to run netstat as usual, pressing enter too fast to realize that tab auto-completed to netst instead of netstat.
This is just one example, I could easily think of more. Having . on $PATH is a security risk, that's why it's never there by default in any system. Appending . to the end is better than prepending it, but it's really best to not do it at all. Typing the ./ in front of programs should not be too much of a hassle, and you have the peace of mind of knowing exactly what you're running.
I think the conclusions in the duplicate questions are too soft:
https://superuser.com/questions/156582/why-is-not-in-the-path-by-default
https://unix.stackexchange.com/questions/65700/is-it-safe-to-add-to-my-path-how-come
Nobody should ever do this. The convenience this gives is ridiculously small compared to the dangers.
That's a good way to do it if you need it.
One reason it's not included by default is that malicious packages (of any kind, like tgz) can contains programs named the same as system commands that will remove things, start viruses or small daemons for future DDoS attacks.
What if a pack contains a program called emacs or vi? That besides showing the directory or change working directory also does something else?
So before putting that in your path consider what you will download.
Personally I'm happy with running ./local_program instead of putting it on the path.
The dangers of putting . in your $PATH are easy to find in other SO answers, so I'll just concentrate on "is there a better way to do [it]?". If "[it]" is "run my scripts without annoying punctuation," then the better way is to put all of your scripts in a directory called, for example, ~/bin, and add that to your $PATH.
You still need to be careful about what you put into that directory, and you will still have to avoid reusing names of built-ins as executables (test and time are popular bad names), but it doesn't open you up to random exploits or unexpected consequences of typing ls from the wrong directory.
I was going through the source code of a rainmeter skin and i could not understand :
TextShortcut1=Computer
TextShortcut2=Libraries
TextShortcut3=Internet
TextShortcut4=Media Player
TextShortcut5=Control Panel
TextShortcut6=Trash
TextShortcut7=ShutDown
TextPath1=::{20D04FE0-3AEA-1069-A2D8-08002B30309D}
TextPath2=shell:Libraries
TextPath3=http://google.com
TextPath4=shell:MusicLibrary
TextPath5=::{21EC2020-3AEA-1069-A2DD-08002b30309d}
TextPath6=::{645FF040-5081-101B-9F08-00AA002F954E}
TextPath7=rundll32.exe user32.dll LockWorkStation
Can anyone tell me what
::{20D04FE0-3AEA-1069-A2D8-08002B30309D}
::{21EC2020-3AEA-1069-A2DD-08002b30309d}
::{645FF040-5081-101B-9F08-00AA002F954E}
these are
and also how can we get one of these for a specific location from our computer.
Those are CLSID (Windows Class Identifiers). Certain special folders within the operating system are identified by unique strings.
20D04FE0-3AEA-1069-A2D8-08002B30309D is My Computer
21EC2020-3AEA-1069-A2DD-08002b30309d is Control Panel
645FF040-5081-101B-9F08-00AA002F954E is Recycle Bin
Source:
http://www.sevenforums.com/tutorials/110919-clsid-key-list-windows-7-a.html
In response to the comment:
can i have Class Identifiers for any folder on Computer or is it just
the bunch of those.
There isn't much reason for you to add more clsids, since you can just go to other locations by typing the normal path. This is a set list that is in the registry somewhere for special folders that don't really have "paths" like C:\windows does.
what is "shell:Something" is it a cmd command or location
shell: is similar to above. It is a convenient way of accessing special folders. Here is a good site for a list: http://smallvoid.com/article/winnt-shell-keyword.html . It is more of a shortcut for Windows Explorer to access a specific location than it is a command. You cant use them in batch files as far as I know (no command line stuff).
what is %something% like %temp%
Those are environment variables. You can usually count on certain ones existing, but the user can change these. Here is a list of some more: http://en.wikipedia.org/wiki/Environment_variables#Microsoft_Windows
how do they all differ?
Well, basically, they are just different ways of accessing the same thing. Some things are more backwards compatible than others, so you have to make that choice when the time comes. If you know your app is going to be on Windows 7 and above, you can make use of some of the more convenient shell:something ones. But if it needs to run on Windows 2000, you might have to rely more on older stuff like environment variables. Environment variables can also be customized by the user.
I have a program that I need to run under *nix and windows. because the program takes file paths from files the issue is what to do about the \ vs / issue.
My current thought is to put in a regex that converts the wrong one to the right one depending on what system I'm on. This will have the effect of letting either type work on either system. Aside from the fact that now I have two problems, does anyone see any other problems?
(Other better solutions are more than welcome)
Edit: the primary issue is getting windows paths to work on unix rather than the other way around.
The / is fully supported in win32 too.
Also see this related question
Windows will generally accept either \ or /,so standardizing on / may make your problem simpler as long as you have complete control over the filenames.
Have you considered creating a "file manager" class that will handle all of the file pathing issues for you? That way in your mail application, when you're loading a data file, you can call something like this.
LoadApplicationData(FileManager.GetDataFilePath)
Then your file manager will detect the environment that it is in and return the proper file path option. That way you can also accomodate for Win32 vs. Unix locatio standards (like Program Files vs /usr or whatever) as well.
Note that Win32 paths are complex when you consider drive letters (no analog on Unix) and the special 'forks' (MacOS pre-X term - likewise no analog on Unix in general, though MacOS X has them - surprise, surprise) that can be provided. Be careful.
Create a parser for your input to create a tree structure of nodes representing directories. Then you can 'save' by walking the tree and writing whatever delimiters you want or optionally doing different things, like checking if the directory exists or writing meta files. This is actually something that I am just now thinking would be useful for my own application :-)
You didn't say what language you are using, so I'm going to selfishly assume c/c++. boost, if you are willing to use it, has a filesystem library. Of course, if you are using a dynamic language, FS abstraction libraries probably already exist there too (e.g. in perl, File::Spec is quite standard).
You haven't told us what sort of files you are reading paths in from. I am going to assume that they are config files. In which case, there are many ways, IMHO the correct answer is to design your program to avoid manipulating paths, if possible. I posted an answer here: https://stackoverflow.com/a/40980510/2345997 which is relevant.
ways:
Add a command line option which allows a user to specify the path in question instead of reading it from a config file.
Add a command line option so that the user can specify a base path. Paths in the config file will be interpreted as located under this base path.
Split your config file into three. One file will have cross platform configuration, another file will have windows only configuration and a final file will have Linux only configuration. Then the user can specify the correct path for both Windows and Linux. On windows your program will read the cross-platform config file and the windows only config file. On Linux it will read the cross-platform file and the Linux only config file.
Add preprocessing to your config file parsing. This will allow you to have one config file where the user can make your program ignore some of the lines in the file depending on which OS the program is running on. Therefore, the user will be able to specify the path to the file twice. Once for Linux, and once for Windows.
Change the design so that the files are always located in the same directory as your executable - then the user only specifies file names in the config file rather than paths to files.
Use a simple function that switches "/" to "\". Then document to the user that they must specify paths as Linux paths and this transformation will be applied for windows.
Create your own path mini-language for this and document it to the user. E.g: "/" - specifies a directory separator, {root} - expands to the root of the filesystem, {cwd} - expands to the current directory, {app} - expands to the path to your application etc... Then the user can specify file paths like: {root}/myfiles/bob.txt on both platforms.
Some paths will work on both platforms. E.g: relative paths like ../my files/bill.txt. Restrict your application to only work with these paths. Document this limitation and how your application handles paths to the user.