How can I run a command as another use + use user's environment/config variables from home folder in Linux? - linux

I have a lot of configuration for Kwin (the window manager) in another user's home folder (/home/B/.config and other folders).
Is there a way to run Kwin from my session, but make Kwin consider the other user's configuration and environment as well?
I can't copy the files over to my account because they're scattered around B's home folder, and I don't want to risk overwriting stuff.
I tried using sudo, but it doesn't run the command as if it was the B's session, and uses my own config files to run the program instead of those in /home/B/.

If the -H sudo parameter is not enough, maybe you also need something from shell resource files that -i would give you, so something like sudo -i -uusername command.
From sudo's man page:
-i, --login Run the shell specified by the target user's password
database entry as a login shell. This means that
login-specific resource files such as .profile or
.login will be read by the shell. If a command is
specified, it is passed to the shell for execution
via the shell's -c option. If no command is
specified, an interactive shell is executed. sudo
attempts to change to that user's home directory
before running the shell. The command is run with an
environment similar to the one a user would receive
at log in. The Command environment section in the
sudoers(5) manual documents how the -i option affects
the environment in which a command is run when the
sudoers policy is in use.

Related

How to Change my default shell on server?

I was assigned an account for log in to a remote server, and I want to change my default shell.
I tried chsh command but it says: chsh: "/public/home/{my_id}/bin/zsh" is not listed in /etc/shells.
If you don't have permission to install zsh system wide, a quick fix is to append exec ~/bin/zsh -l to ~/.bash_profile (if bash is the current shell), or an equivalent rc file for the current login shell.
zsh -l starts zsh as a login shell.
exec COMMAND replaces the current process with COMMAND, so you'll only have to type exit (or press ctrl+d) once.
~/.bash_profile is executed when bash starts as a login shell, you can still run command bash normally.
Depending what is in ~/.bash_profile (or equivalent), you may wish to avoid executing its other contents, by putting exec ~/bin/zsh -l at the start of the file (not the end), and copy/port anything important over to the zsh equivalent, $ZDOTDIR/.zprofile.
I might also do export SHELL="$HOME/bin/zsh", although I'm unsure of the full effects of setting SHELL differently to that specified for your user in /etc/passwd, to a shell not in /etc/shells, and to a shell binary in your home path.
First check all the shells available on your linux system
cat /etc/shells
Use chsh command line utility for changing a login shell with the -s or –shell option like this.
# chsh --shell /bin/sh tecmint

How to update the /etc/profile within the sudo bash without rebooting or logging out

Currently right now I am creating a script that updates the path and environment variable of the profile within my raspberry-pi
I have created a script within the /etc/profile.d/sdk.sh to create a environment variable. Now it does not updates within my env, How can I add/update my environment variable without rebooting or logging-out of the system.
My script:
SDK_SH_FILE="/etc/profile.d/sdk.sh"
EXPORT_SDK_HOME="export SDK_HOME=/edit/"
echo -e "$EXPORT_SDK_HOME" > "$SDK_SH_FILE"
It is run using: cat my-script | sudo bash
Currently it is not updating my env unless I logout or reboot the system.
After editing sdk.sh, you need to load it in the current shell with:
source /etc/profile.d/sdk.sh
You have two choices for this job:
source /etc/profile.d/sdk.sh
OR
. /etc/profile.d/sdk.sh
I have just tried out Barmar's suggestion. It works to update the current bash session. If you close the terminal window and open a new one, you need to run source again.
Also, the new values are only concatenated to the environment variable rather than replacing the old values. So, it is still better to log out and log in again.
You can update the current shell environment by sourcing a script, because that way it runs in the same shell instance, but you need to acquire privileges to update sdk.sh (so shell redirections won't work), right?
The solution is to separate the write operation that requires privileges (calling only that via sudo).
Here the UNIX toolbox comes to the rescue with tee, a program that takes files as parameters, reads from it's standard input, and copies to it's standard output and to the files specified as parameters; this being a separate program, and opening it's parameters on it's own, can be called with sudo just fine.
Solution
export SDK_HOME=/edit/
typeset -p SDK_HOME | sudo tee /etc/profile.d/sdk.sh >/dev/null
Now, you need to source this file, instead of calling it, like so:
. ./my-script.
Here I used typeset -p to avoid repeating myself, it reproduces the declarations of the specified variables.
Variables and startup files
Variables are handed down from process to process in the environment, which is a portion of memory every process gets from it's parent process.
Shells behave differently depending on how they're called; a login shell will load a user/system profile file, i.e. /etc/profile (or a similar file at the home directory), and the rest of the session will get variables from it through the environment (thus updates to the file don't matter); normally all other interactive instances of the shell load a secondary file, in the case of BASH it's $HOME/.bashrc or /etc/bashrc (which login shells don't load).

System Shell Scripts Can't Find my Command in PATH

I put a custom command (shell script) in /usr/local/scripts/.
In order to see commands from /usr/local/scripts, I set the PATH using the following methods:
sudo visudo
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/scripts"
sudo nano /etc/profile
PATH="$PATH:/usr/local/scripts"
export PATH
sudo nano /etc/login.defs
ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/scripts
ENV_PATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games:/usr/local/scripts
sudo nano /root/.bashrc
PATH="$PATH:/usr/local/scripts"
export PATH
sudo nano /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/local/scripts"
And this works in most cases, but...
I have two script which, in their code, calls a script from /usr/local/scripts/, and it can't find my script!
The first is /etc/network/if-up.d/sendip, which is run as root when the networking stack is initialized.
And the second is /usr/local/scripts/notif-login which is run as root from pam by /etc/pam.d/sshd:
session optional pam_exec.so /usr/local/scripts/notif-login
If I run both script from my terminal shell, another user, with sudo, without sudo, after su, or login with root, it works properly. But when it is runner by the system (first when networking initialized, and the second via SSH) both failed to run scripts from /usr/local/scripts.
Is there another place where I have to set the path?
Bash/sh will not read /etc/profile for "non-interactive shells", such as the shells from which the scripts you mention run. I'm not sure which distribution you're using, but you should just be able to add it to /etc/environment's PATH definition. Ob Ubuntu, for example:
Change:
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
To:
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/local/scripts"
Edit
This should work under Raspbian; it does under Debian. If it doesn't, you might need to just modify the path at the start of one of your scripts. None of the normal startup files will execute for a non-interactive session under Bash. Also try outputting $SHELL and make sure the script is running under the shell you think it is.

modifying /etc/profile linux

I need to change the greeting of user, which is logging in. So I modifyed file /etc/profile. In this greeting I need to know, which shell this user use and tell it to user. The problem is that then I change my shell on zsh or csh it doesnt work. Even if I just type in this file echo $SHELL it do nothing. As I think, when I use csh and zsh this file (/etc/profile) doesnt run at all. How can I fix this problem?
Thanks you, sorry for my English)
You should start by reading the manpage of every shell on your system.
There are different flavours of shells. Each flavours uses slightly different (per session and per shell, per site and per user) initialisation files. For example:
sh (and bash) use /etc/profile and ~/.profile
bash also uses ~/.bash_profile, ~/.bashrc, ~/.bash_logout
csh uses /etc/.login and ~/.cshrc
etc...
The above list is not meant to be exhaustive. It is to illustrate you will need to check the exact behaviour of each shell that is used on your system and configure it appropriately.
You also need to consider whether you want to change system-wide behaviour (corresponding to initialisation files under /etc) or user-specific behaviour (corresponding to initialisation files in the user's home directory).
For certain shells, there's also per-session (i.e. once per login) and per-shell settings (e.g. for every terminal window). A good example is ~/.bash_login (executed once per login) and ~/.bashrc (executed for every shell - e.g. terminal window).
They both execute different files:
From fro zsh http://zsh.sourceforge.net/Guide/zshguide02.html
Now here's a list of the startup files and when they're run. You'll
see they fall into two classes: those in the /etc directory, which are
put there by the system administrator and are run for all users, and
those in your home directory, which zsh, like many shells, allows you
to abbreviate to a `~'.
/etc/zshenv
Always run for every zsh.
~/.zshenv
Usually run for every zsh (see below).
/etc/zprofile
Run for login shells.
~/.zprofile
Run for login shells.
/etc/zshrc
Run for interactive shells.
~/.zshrc
Run for interactive shells.
/etc/zlogin
Run for login shells.
~/.zlogin
for csh http://unixhelp.ed.ac.uk/CGI/man-cgi?csh+1
A login shell begins by executing commands from the system files
/etc/csh.cshrc and /etc/csh.login.
You can make a soft link to point to the same file:
ln -s /etc/profile /etc/zshenv
ln -s /etc/profile /etc/csh.login
I have modified my etc/profile file to start a python script on startup. now my program is running but there is a black screen, because my program has a while True loop in it and now I am not able to stop it. Kindly tell me how to stop the program, I have tried ctrl+C but nothing happened.

Add source to bash

In my Debian server, all users run sh, but root runs bash;
when i start a ssh connection, i log in with my personal account that does not have root privileges;
i've installed rvm and I want to use it as root because using it from my personal user, it fails installing everything since the user does not have permissions to write where is neeeded; so everytime i need to type
source /usr/local/rvm/bin/rvm
before being able to use rvm; to avoid typing source command everytime, in sh i know i can put the command in /etc/profile file; is there something similar for bash?
I've tried to add "echo aaa" to /etc/profile, to see what happen;
when i login as my personal user, i get the "aaa" output; but when i type su and login as root, nothing happens... I think that when i use "su" command and login as root, the /etc/profile is not read
The same happens after installing by rvm a ruby release: I setup the default ruby version (as root) and then the ruby command is available for my personal user (but if i do "su" again and try to type "ruby -v" as root, i get "command not found"
Another thing: after login with my personal user, the rvm command is available; after typing "su", no more; if I add the source command to /etc/profile, once login is done with personal user, i can see a screen output from rvm (some kind of doc); the same happens after using the source command as root
bash -- being an extension of sh -- also reads /etc/profile.
bash specific alternatives include ~/.bash_profile for login shells, and ~/.bashrc and for non-login shells.
/etc/bash.bashrc is the global config for bash, though /etc/profile is usually sourced by bash as well.
You may need to run the command with 'sudo' in order to actually run it as root. I believe the shell config scripts for any shell will run as the user that is launching the shell. If you prefer, you could also run the binary in an 'sh' shell as well:
sudo /bin/sh -c /usr/local/rvm/bin/rvm
Here's some more info, just in case: https://wiki.debian.org/sudo

Resources