I am trying to run psql with user postgres. When I run sudo su - postgres AND THEN psql from within the new session, it is working smoothly. In fact, the ~/.bashrc in that session with use postgres has the correct PATH.
However, if I run sudo -u postgres psql, I get sudo: psql: command not found. Even though the session where I am running this command (I use the FISH shell) has the correct PATH as well, and I can invoke psql without the full path with my user.
I need to invoke the command as sudo -u postgres psql, how can this behavior be explained?
Edit: if (from FISH) I switch to BASH and run sudo -u postgres psql, it works! I guess it has to do with the FISH path then...
Edit 2: The issue seems to be that the PATH is reset when using sudo.
➜ ~ psql
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: role "opc" does not exist
➜ ~ sudo -u postgres psql
sudo: psql: command not found
➜ ~ echo $PATH
/home/opc/.local /home/opc/.local/bin /usr/pgsql-15/bin /usr/pgsql-15/bin /usr/local/bin /usr/bin /usr/local/sbin /usr/sbin
➜ ~ sudo echo $PATH
/home/opc/.local /home/opc/.local/bin /usr/pgsql-15/bin /usr/pgsql-15/bin /usr/local/bin /usr/bin /usr/local/sbin /usr/sbin
➜ ~ sudo -u postgres /usr/pgsql-15/bin/psql
could not change directory to "/home/opc": Permission denied
psql (15.1)
Type "help" for help.
postgres=#
But if I echo $PATH with sudo, it seems fine...
This is caused by a sudo configuration that has the "secure_path" setting. This causes sudo to reset $PATH to a hardcoded "known safe" value. This might be enabled by your distribution.
When you run sudo bash, that bash will read its settings, including .bashrc, and if you set $PATH in that it will then, of course, have that $PATH again.
But if you run a command without going through a shell that resets $PATH, you'll get the hardcoded setting.
It's possible to change that setting by running sudo visudo and changing the line that says
Defaults secure_path="some:path:here"
to
Defaults !secure_path
An alternative is to just run the command via the fully qualified path, like
sudo -u postgres (command -s psql)
One more comment about your tests:
sudo echo $PATH
This doesn't do what you want. The $PATH will be expanded by the shell that runs sudo, and so sudo won't ever see anything but the value of it. It is exactly equivalent to running sudo echo /home/opc/.local /home/opc/.local/bin /usr/pgsql-15/bin ....
You might want to use something like
sudo env
or
sudo sh -c 'echo $PATH'
instead.
Related
I have developed a shell script whose job is to take the dump of postgres DB. Below is the snippet:
#!/bin/sh
today=$(date +"%Y-%m-%d")
yes "password" | sudo -S sudo su - postgres <<EOF
/usr/pgsql-11/bin/pg_dump -U postgres -d db_name > /home/db_backup/db_name_$today.sql
EOF
exit
However, this script is NOT running because of the below reason:
[sudo] password for user: Sorry, Try again
However, when I use sudo su - postgres and then provide password, it is working as expected. And interestingly, if now I run the above shell script after the login, it runs absolutely fine.
What I am missing here.
It is dangerous to store passwords in scripts, so please do not do it.
Modify your /etc/sudoers file by running sudo visudo and adding a line like this at the bottom:
%sudo ALL=(postgres) NOPASSWD: /usr/bin/psql
This allows anyone with sudo permission to run /usr/bin/psql to postgres on any host (ALL) with no password.
Now your script should work this way:
#!/bin/sh
today=$(date +"%Y-%m-%d")
sudo -b -n -H -u postgres /usr/pgsql-11/bin/pg_dump -U postgres -d db_name > /home/db_backup/db_name_$today.sql
Make sure postgres can write to the directory /home/db_backup/.
Problem
when in tried run sql file in psql shell...
give "No such file or directory" error!
$ ls
config.sql config.yaml
$ sudo -i -u postgres psql
postgres=# \i config.sql
config.sql: No such file or directory
thanks for your reply!
Quick solution:
-i => goes to user's home directory!
as result ./config.sql address is incorrect!
just use
$ psql -U <user_name>
postgres=# \i config.sql
man sudo tells you:
-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, .bash_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.
In particular, that will set your current working directory to the home directory of user postgres.
If you want to avoid that, don't use '-i'.
I have postgres installed on an ubuntu machine, and I am able to enter into the command line via something along the lines of:
$ sudo -u postgres psql
psql (10.15 (Ubuntu 10.15-0ubuntu0.18.04.1))
Type "help" for help.
postgres=#
And I can start/stop the server by doing something like:
$ sudo service postgresql
Usage: /etc/init.d/postgresql {start|stop|restart|reload|force-reload|status} [version ..]
Those both seem fine. However, I would like to run postgres in single-user mode to do a couple tests. On the postgres page it gives a few examples, such as:
To start a single-user mode server, use a command like
postgres --single -D /usr/local/pgsql/data other-options my_database
However, if I use the 'postgres' command, I just get an error saying I don't have that command:
$ postgres
Command 'postgres' not found, did you mean:
What do I need to install to run the 'postgres' command in order to enter single-user mode?
as you have not export the binary path that's why it's can't find your binary of postgres.
use this command:
/usr/lib/postgresql/10/bin/postgres --single -D /usr/local/pgsql/data other-options my_database
or,
you can export the path in bash
first open the bashrc with this command:nano ~/.bashrc
add this line in the end :PATH="/usr/lib/postgresql/10/bin/:$PATH"
run this command source ~/.bashrc
the just use postgres --single -D /usr/local/pgsql/data other-options my_database
you can also find where your binary is with this command : find /usr/lib -iname 'postgres'
It is already installed, it is just not in your PATH, as it is not anticipated you would use it manually.
It is probably somewhere like "/usr/lib/postgresql/10/bin/postgres", or you can use locate or find to find it.
Ubuntu has conf files spread over several places so:
/usr/lib/postgresql/13/bin/postgres --single -D /var/lib/postgresql/13/main -c "config_file=/etc/postgresql/13/main/postgresql.conf"
I install Postgresql on my Ubuntu with:
brew install postgres
now I have:
psql --version
psql (PostgreSQL) 9.5.0
How can I start the service automatically?
On my Mac with homebrew I can do it with:
ln -sfv /usr/local/opt/postgresql/*.plist ~/Library/LaunchAgents
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
but how on Ubuntu with Linuxbrew?
I try with:
brew services start postgresql
but it says:
sh: 1: list: not found
Error: Could not read the plist for `postgresql`!
What to do?
Not quite automatic but a step in the right direction. On my system I did the following:
$ pg_ctl start -D $HOME/.linuxbrew/var/postgres -l logfile
You could simple create an alias in your .bash_profile or .bashrc something like:
alias poston="pg_ctl start -D $HOME/.linuxbrew/var/postgres -l logfile"
alias postoff="pg_ctl stop -D $HOME/.linuxbrew/var/postgres"
To test it all out (assuming you do not yet have a database on your machine) you can also create a database for your current user:
$ poston
$ createdb `whoami`
$ psql
Can anyone explain this:
~$ echo $PGDATA
/Library/PostgreSQL/9.2/data
~$ cd /Library/PostgreSQL/9.2/
/Library/PostgreSQL/9.2$ sudo su postgres
bash-3.2$ echo $PGDATA
<blank line>
bash-3.2$ pg_ctl start
pg_ctl: no database directory specified and environment variable PGDATA unset
Try "pg_ctl --help" for more information.
bash-3.2$ export PGDATA="/Library/PostgreSQL/9.2/data"
bash-3.2$ pg_ctl start
server starting
bash-3.2$
The following is in my ~/.bashrc file:
export PGDATA="/Library/PostgreSQL/9.2/data"
I'm not mis-spelling the path in PGDATA:
~$ echo $PGDATA
/Library/PostgreSQL/9.2/data
export PGDATA="/Library/PostgreSQL/9.2/data"
sudo can't be assumed to keep the environment variables of its caller.
See its manpage for the details with your specific OS.
As far as I know, environment variables are attached to a shell, and as far as I can tell I'm in the same shell.
This works for me:
~$ cd /Library/PostgreSQL/9.2/
/Library/PostgreSQL/9.2$ sudo -E su postgres
...
-E The -E (preserve environment) option will override the
env_reset option in sudoers(5)). It is only available when
either the matching command has the SETENV tag or the
setenv option is set in sudoers(5).
I only understand the following:
The -E (preserve environment) option
Next comment:
When I su to postgres I do su - postgres. Notice the hyphen.
Here is what my man pages say about the hyphen:
-l Simulate a full login. The environment is discarded except for
HOME, SHELL, PATH, TERM, and USER. HOME and SHELL are modified
as above. USER is set to the target login. PATH is set to
``/bin:/usr/bin''. TERM is imported from your current environ-
ment. The invoked shell is the target login's, and su will
change directory to the target login's home directory.
- (no letter) The same as -l.
I don't see how that will preserve the PGDATA environment variable, and this is what happened when I tried the hyphen:
/Library/PostgreSQL/9.2$ sudo su - postgres
Password:
7studs-computer:~ postgres$ ls
bin pgAdmin3.app
data pg_env.sh
doc scripts
include share
installer stackbuilder.app
lib uninstall-postgresql.app
7studs-computer:~ postgres$ pg_ctl start
-bash: pg_ctl: command not found
7studs-computer:~ postgres$ ls
bin pgAdmin3.app
data pg_env.sh
doc scripts
include share
installer stackbuilder.app
lib uninstall-postgresql.app
7studs-computer:~ postgres$ cd bin
7studs-computer:bin postgres$ ls
clusterdb pg_config pgbench
createdb pg_controldata pltcl_delmod
createlang pg_ctl pltcl_listmod
createuser pg_dump pltcl_loadmod
dropdb pg_dumpall postgres
droplang pg_receivexlog postmaster
dropuser pg_resetxlog psql
ecpg pg_restore reindexdb
initdb pg_standby vacuumdb
oid2name pg_test_fsync vacuumlo
pg_archivecleanup pg_test_timing
pg_basebackup pg_upgrade
7studs-computer:bin postgres$ ./pg_ctl start
pg_ctl: no database directory specified and environment variable PGDATA unset
Try "pg_ctl --help" for more information.
7studs-computer:bin postgres$
So the hyphen doesn't work for me (OSX 10.6.8).