LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > CentOS
User Name
Password
CentOS This forum is for the discussion of CentOS Linux. Note: This forum does not have any official participation.

Notices


Reply
  Search this Thread
Old 11-16-2017, 11:11 AM   #1
bodisha
Member
 
Registered: Oct 2016
Posts: 30

Rep: Reputation: Disabled
Non-interactive & non-login shell environment?


Hello and thanks in advance for any help anyone can offer to straighten me out on this subject

I'm trying to understand non-interactive & non-login shells and having a hard time conceptualize the process a non-interactive & non-login shell goes through to start up. The way I understand things is when a script or a process is started.... a region of memory is created and the child process replicates a duplicate environment of the parent by being forked

What's confusing me is when is the shell environment defined? When I think about how an interactive shell is started I get a little lost.

The way I understand an interactive shell is:
1) User passes login ID to Linux kernel 2) Linux kernel looks the user up in the /etc/password file and identifies the assigned shell 3) the shell is started 4) the shell reads the login scripts to define the shell environment for the user 5) Linux produces a command prompt to indicate the shell is ready to accept commands

Is the process for a non-interactive & non-login shell similar? This is how I envision it working:
1) The process is forked by the parent process 2) Linux identifies the user ID the process will runs as 3) Linux looks the user id up in the /etc/password file 4) the shell is started 5) the BASH_ENV is read (If it was defined) 6) the process interacts with the shell to pass commands to the API

For some reason this seems clunky and like I'm missing something... Could someone let me know if I'm on the right path please?

Thank you very much!
 
Old 11-16-2017, 11:20 AM   #2
MensaWater
LQ Guru
 
Registered: May 2005
Location: Atlanta Georgia USA
Distribution: Redhat (RHEL), CentOS, Fedora, CoreOS, Debian, FreeBSD, HP-UX, Solaris, SCO
Posts: 7,585
Blog Entries: 15

Rep: Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537
What you're talking about are called "background" processes. These are often started by things such as the startup scripts (e.g. init in CentOS6 and earlier or systemd in CentOS7) or schedulers like cron or a plethora of others.

Such background jobs unlike foreground logins typically have minimal environments based on the tools used. They do NOT typically source startup files such as /etc/profile, $HOME/.bashrc etc... like a login would. This means typically you have to tell the jobs what environment to use. One way to do that is simply by sourcing those other files:
. /etc/profile
. $HOME/.bashrc

The problem with that is many things in those files assume you're on a terminal (or pseudo terminal) of some sort but background processes are not. Given that it is much better if you simply add the environment variables required for the job to the job start (e.g. the init script or the cron job).

It is usual for people to say "It ran from command line but not from init or cron". This blog post explains that in light of what I said above:
https://www.linuxquestions.org/quest...-script-36931/

Last edited by MensaWater; 11-16-2017 at 11:21 AM.
 
Old 11-16-2017, 01:42 PM   #3
bodisha
Member
 
Registered: Oct 2016
Posts: 30

Original Poster
Rep: Reputation: Disabled
Thanks for the quick reply! I hope you don't mind a follow up question

After read your post and giving it some thought.... I guess my ultimate question is about background process... After one starts up does it interact with a shell? I understand every process has a user ID associated with it... and that user ID has a shell (of one sort or another) defined in the /etc/passwd file.... But do background processes actually interact with a shell somehow? I was almost of the impression background process issued commands directly to the API

So as an example... An Oracle database requires the user ID of oracle with the /bin/bash shell associated with it. I'm confused about when does that process interact with the shell? Meaning does a process owned by oracle use the bash shell to pass commands to the API?


Thanks for the help straightening me out! I appreciate it!!!

Last edited by bodisha; 11-16-2017 at 03:11 PM.
 
Old 11-16-2017, 04:36 PM   #4
MensaWater
LQ Guru
 
Registered: May 2005
Location: Atlanta Georgia USA
Distribution: Redhat (RHEL), CentOS, Fedora, CoreOS, Debian, FreeBSD, HP-UX, Solaris, SCO
Posts: 7,585
Blog Entries: 15

Rep: Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537
The process doesn't necessarily have to have bash (or ksh or csh) running if it has been spawned though may have started with such a shell.

For example for Oracle DB you might see processes such as:
ps -ef |grep "ora_...._DEV"
devora 1235 1 0 Sep17 ? 00:23:39 ora_pmon_DEV
devora 1237 1 0 Sep17 ? 00:12:05 ora_psp0_DEV
devora 1251 1 0 Sep17 ? 00:13:00 ora_vktm_DEV
devora 1255 1 0 Sep17 ? 00:02:00 ora_gen0_DEV
devora 1257 1 0 Sep17 ? 00:03:07 ora_diag_DEV
devora 1259 1 0 Sep17 ? 00:02:56 ora_dbrm_DEV
devora 1261 1 0 Sep17 ? 07:19:15 ora_dia0_DEV
devora 1263 1 0 Sep17 ? 00:02:04 ora_mman_DEV
devora 1265 1 0 Sep17 ? 00:04:09 ora_dbw0_DEV
devora 1267 1 0 Sep17 ? 00:03:44 ora_dbw1_DEV
devora 1269 1 0 Sep17 ? 00:03:25 ora_dbw2_DEV
devora 1272 1 0 Sep17 ? 00:03:28 ora_dbw3_DEV
devora 1274 1 0 Sep17 ? 00:03:26 ora_dbw4_DEV
devora 1276 1 0 Sep17 ? 00:03:20 ora_dbw5_DEV
devora 1278 1 0 Sep17 ? 00:03:22 ora_dbw6_DEV
devora 1280 1 0 Sep17 ? 00:03:19 ora_dbw7_DEV
devora 1282 1 0 Sep17 ? 00:03:23 ora_dbw8_DEV
devora 1284 1 0 Sep17 ? 00:03:22 ora_dbw9_DEV
devora 1286 1 0 Sep17 ? 00:15:49 ora_lgwr_DEV
devora 1288 1 0 Sep17 ? 00:44:28 ora_ckpt_DEV
devora 1290 1 0 Sep17 ? 00:11:10 ora_smon_DEV
devora 1293 1 0 Sep17 ? 00:00:43 ora_reco_DEV
devora 1295 1 0 Sep17 ? 00:27:45 ora_mmon_DEV
devora 1297 1 0 Sep17 ? 04:02:18 ora_mmnl_DEV
devora 1414 1 0 Sep17 ? 00:01:41 ora_qmnc_DEV
devora 1429 1 0 Sep17 ? 00:16:18 ora_cjq0_DEV
devora 1495 1 0 Sep17 ? 00:00:52 ora_q002_DEV
devora 1498 1 0 Sep17 ? 00:02:39 ora_q003_DEV
devora 2608 1 1 Sep26 ? 15:25:44 ora_m000_DEV
devora 3853 1 0 Sep17 ? 00:02:52 ora_smco_DEV
devora 23363 1 0 16:18 ? 00:00:00 ora_w000_DEV
The second column is the process ID (PID) and the 3rd columns is the parent process ID (PPID). All of those processes show "1" as PPID. 1 is "init" and it is the parent of any process that doesn't have another process. Notice the 6th column is "?" indicating these are all background processes not associated with a terminal.

A shell script is actually used to start this instance and it calls Oracle which starts each of these PIDs. The environment used when starting that script is inherited by each of these processes but there could be things within the processes themselves that are adding, removing or modifying environment variables appropriate to their run.

Compare that to a Postgres list of processes:
ps -ftpts/1
UID PID PPID C STIME TTY TIME CMD
postgres 7567 21856 0 Oct25 pts/1 00:00:00 psql -U redacted redacted
root 21805 24724 0 Oct25 pts/1 00:00:00 sudo su - postgres
root 21855 21805 0 Oct25 pts/1 00:00:00 su - postgres
postgres 21856 21855 0 Oct25 pts/1 00:00:00 -bash
user1 24724 18774 0 Oct25 pts/1 00:00:00 -bash
postgres 28810 1 0 Oct25 pts/1 00:00:35 /database/fio/postgresql/pgsql-1

In that we can see that user1 logged into terminal pts/1 and had a bash shell as user1. He used sudo su to switch to a user named postgres" wwhich spawned another shell. In that shell he then ran a a command to He then ran a command to attach to the database and start it (PID 28810). That PID in turn became the PPID of additional processes as shown below:
postgres 28811 28810 0 Oct25 ? 00:00:00 postgres: logger process
postgres 28813 28810 0 Oct25 ? 00:00:07 postgres: checkpointer process
postgres 28814 28810 0 Oct25 ? 00:00:49 postgres: writer process
postgres 28815 28810 0 Oct25 ? 00:01:40 postgres: wal writer process
postgres 28816 28810 0 Oct25 ? 00:00:41 postgres: autovacuum launcher process
postgres 28817 28810 0 Oct25 ? 00:01:44 postgres: stats collector process
postgres 28818 28810 0 Oct25 ? 00:00:01 postgres: bgworker: logical replication launcher

Notice that even though the real user and the switch to postgres user both have (separate) bash shells and are on terminal pts/1 the resulting processes are NOT children of either bash shell nor are they associated with that terminal. Despite all this they would have inherited the environment of the postgres user that invoked the command that spawned them.
 
Old 11-16-2017, 06:30 PM   #5
bodisha
Member
 
Registered: Oct 2016
Posts: 30

Original Poster
Rep: Reputation: Disabled
Thanks for the reply! I hope you don't mind a follow up question

You said

Quote:
The process doesn't necessarily have to have bash (or ksh or csh) running if it has been spawned though may have started with such a shell.
I'm struggling to understand how a background process passes commands to the kernel. From what I've read a child process should inherit its parent environment during the fork procedure... and once it's up and running the process hands commands off to the API.

The oracle instructions say to create a user ID named oracle, assign the /bin/bash shell to it, and create a ~/.bash_profile file set the umask to 022. From what's read in the Bash man page the ~/.bash_profile is read for login shells.

My understand though is a database process, like this, should start in a non-interactive & non-login shell.... And according to the Bash man page it should read the BASH_ENV variable... not a /.bash_profile script

Quote:
~/.bash_profile
The personal initialization file, executed for login shells
Quote:
When bash is started non-interactively, to run a shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it appears there, and uses the expanded value as the name of a file to read and execute.
So I'm kind of at odds with what I've been reading about how Bash and background processes work and what I'm seeing in the Oracle documentation... If I could ask you to step me through this I would be extreme grateful! I'm managed to confuse the hell outta myself here

Once again... thank you very much!

Last edited by bodisha; 11-16-2017 at 06:31 PM.
 
Old 11-17-2017, 10:28 AM   #6
MensaWater
LQ Guru
 
Registered: May 2005
Location: Atlanta Georgia USA
Distribution: Redhat (RHEL), CentOS, Fedora, CoreOS, Debian, FreeBSD, HP-UX, Solaris, SCO
Posts: 7,585
Blog Entries: 15

Rep: Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537Reputation: 1537
Few user processes talk directly to the kernel. It is an hierarchy of processes starting with PID 1 which is "init". Ultimately in ever process tree init will be at the top (or bottom depending on point of view). Some processes you can see have 1 as PPID. Others you'll see have a different PPID and in turn the PPID of that parent may have yet another and so on but ultimately you'll see a PID that has 1 as the PPID if look at the tree.

Quote:
Originally Posted by bodisha View Post
The oracle instructions say to create a user ID named oracle, assign the /bin/bash shell to it, and create a ~/.bash_profile file set the umask to 022. From what's read in the Bash man page the ~/.bash_profile is read for login shells.
It is true that logins do read startup files such as /etc/profile, /etc/bashrc, $HOME/.bash_profile etc... It is NOT true that only logins CAN do this - it is just that by design logins do. You can source any of these files in a script but as I noted before you sometimes don't want to source those files because they are doing things that make sense for a logged in user but not a background process. A background process is not going to have a terminal.

Given that, it is often done that instead of sourcing the standard login files you create a completely different file that has all the environment variables you need (e.g. ORACLE_HOME, TNSADMIN) and source that file at startup. You do not have to use BASH_ENV - you can source any file you want at startup. In fact it isn't uncommon to have one file that you're sourcing in turn source other files.

For Oracle it does expect you to create and use a user to run the environment.

For example for the processes I listed yesterday we have a user called "devora". In that user's home is a .bash_profile:
Code:
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

export PATH=$PATH:$HOME/bin

PS1="[`uname -n`] \$PWD > "

. /oracle/dev/devora/11.2.0/DEV_atltst02.env

if [ -t 0 ]; then
    stty erase "^H" kill "^U" intr "^C" eof "^D"
fi

alias l='ls -ltr'
alias la='ls -la'
alias ls='ls --color=none'
The very beginning of that says to look for a file in home called .bashrc and if so source it. Sourcing means to run the file and bring in any settings it generates. (. ./file = sourcing the file, but just ./file = executing the file).

If we look at that .bashrc we see it in turn is sourcing /etc/bashrc:
Quote:
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
/etc/bashrc might be doing settings and might also be sourcing other files in turn.

So if you start a process by running say "su - devora -c <command>" you're telling it to become the devora user with su and with the "-" flag telling it to read in the environment so that it will do the same thing it would do on login. That means (assuming the shell in /etc/passwd for devora is bash) it will load the first file above which will then source the second file then the third (and any others if specified by /etc/bashrc OR anything it sources). All of those settings that were invoked and sourced will be inherite by <command>.

However, if <command> is a script or binary it could be setting its own variables in addition to those inherited, or replacing those inherited or removing (unsetting) those inherited. Often enough <command> is a script. That script might have several variables it is setting and may itself be sourcing other environment files.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] How to clean the shell environment (variables and path) to original login state? someshpr Linux - Newbie 7 03-13-2017 07:50 PM
bash script non-interactive login shell mick66 Linux - Newbie 5 03-17-2015 10:20 AM
BASH Shell Differences: Login or Interactive theKbStockpiler Programming 10 02-21-2011 02:00 AM
How Can Interactive Login Environment Be Duplicated in Cron cmnorton Linux - General 1 05-24-2010 10:17 AM
interactive and non-interactive shell linuxjamil Programming 3 09-03-2006 09:42 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > CentOS

All times are GMT -5. The time now is 06:55 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration