Writing a port for my app and "release asset" meaning

And quite unfortunately, there are no way to set system-wide environment variable.

This is because environment variables can be inherited only from parent process and no way to set environment variable of parent process from its child processes.
For example, if you invoke another shell from command line and set an new environment variable FOO to have value BAR and exit, you cannot see environment variable FOO.

The root parent among all process tree is init(8) and rc scripts which handles /etc/rc.conf is/are one of child process of init(8), thus, cannot affect the environment variables of init(8), AFAIK.

To achieve system-wide environment variable (assuming users of the computer can choose their login shells freely), we would need mechanism to set them in /boot/loader.conf and pass them to init(8) via kernel, maybe via special kenv. But this is not implemented AFAIK.

Another but annoying option would be disallowing any shells other than /bin/sh and set system-wide environmen variable in /.profile or /etc/profile.
 
Sorry, but I'm a bit confused with the sidebar discussion. I'm not sure if it was because I mentioned that I use /opt/info/environment or not but I'm not sure I follow you guys. If it was me that started this, I typically use my /opt/info/env file to keep important information for my setup scripts--which are structured something like below.

But the parent child concept is interesting. Why don't you use a temp file to share the values--and you can take the concept further by using a pipe.

parent-child-temp-file:
Code:
: ${FOO:="foo"}
echo "From parent"
printf -- "The value of FOO is: %s\n" $FOO
echo "$FOO" > ./test.temp

(
    echo "  Whithin child"
    printf -- "  The value of FOO is: %s\n" $FOO
    echo "  Setting the FOO variable to: \"child\""
    FOO="child"
    echo "$FOO" > ./test.temp
)

echo "Back to parent"
read FOO < ./test.temp
printf -- "The value of FOO is: %s\n" $FOO

Example of my setup scripts:
Code:
. /opt/info/environment

: ${ZROOT:="zroot/jails"}
: ${ZROOT_MOUNT:="/usr/local/jails"}                   # Location where jails will be created.
: ${ZROOT_MEDIA:="zroot/jails/media"}                  # media will contain the compressed files of the downloaded userlands.
: ${ZROOT_TEMPLATES:="zroot/jails/templates"}          # templates will contain the templates when using Thin Jails.
: ${ZROOT_CONTAINERS:="zroot/jails/containers"}        # containers will contain the jails.
...

sysrc -f /opt/info/environment ZROOT=${ZROOT}
sysrc -f /opt/info/environment ZROOT_MOUNT=${ZROOT_MOUNT}
sysrc -f /opt/info/environment ZROOT_MEDIA=${ZROOT_MEDIA}
sysrc -f /opt/info/environment ZROOT_TEMPLATES=${ZROOT_TEMPLATES}
sysrc -f /opt/info/environment ZROOT_CONTAINERS=${ZROOT_CONTAINERS}
...

jail_setup() {
        # Setup jail directories.
        zfs create -o mountpoint=${ZROOT_MOUNT} ${ZROOT}
        zfs create ${ZROOT_MEDIA}
        zfs create ${ZROOT_TEMPLATES}
        zfs create ${ZROOT_CONTAINERS}

        # Get a userland.
        if [ ! -f ${ZROOT_MOUNT}/media/14.2-RELEASE-base.txz ]; then
                echo "Fetching jail base to ${ZROOT_MOUNT}/media"
                fetch https://download.freebsd.org/ftp/releases/amd64/amd64/14.2-RELEASE/base.txz -o ${ZROOT_MOUNT}/media/14.2-RELEASE-base.txz
        fi

        # Set up a bridge for VNET.
        echo "Setting up ${CLONED_INTERFACE}"
        sysrc -f /etc/rc.conf cloned_interfaces="${CLONED_INTERFACE}"
        sysrc -f /etc/rc.conf "ifconfig_${DEFAULT_INTERFACE}=-rxcsum -txcsum -lro -vlanmtu -vlanhwcsum -vlanhwfilter -vlanhwtag up"
        sysrc -f /etc/rc.conf "ifconfig_${CLONED_INTERFACE}=addm ${DEFAULT_INTERFACE} up"
        ...
 
Sorry, but I'm a bit confused with the sidebar discussion. I'm not sure if it was because I mentioned that I use /opt/info/environment or not but I'm not sure I follow you guys. If it was me that started this, I typically use my /opt/info/env file to keep important information for my setup scripts--which are structured something like below.

But the parent child concept is interesting. Why don't you use a temp file to share the values--and you can take the concept further by using a pipe.

parent-child-temp-file:
Code:
: ${FOO:="foo"}
echo "From parent"
printf -- "The value of FOO is: %s\n" $FOO
echo "$FOO" > ./test.temp

(
    echo "  Whithin child"
    printf -- "  The value of FOO is: %s\n" $FOO
    echo "  Setting the FOO variable to: \"child\""
    FOO="child"
    echo "$FOO" > ./test.temp
)

echo "Back to parent"
read FOO < ./test.temp
printf -- "The value of FOO is: %s\n" $FOO

Example of my setup scripts:
Code:
. /opt/info/environment

: ${ZROOT:="zroot/jails"}
: ${ZROOT_MOUNT:="/usr/local/jails"}                   # Location where jails will be created.
: ${ZROOT_MEDIA:="zroot/jails/media"}                  # media will contain the compressed files of the downloaded userlands.
: ${ZROOT_TEMPLATES:="zroot/jails/templates"}          # templates will contain the templates when using Thin Jails.
: ${ZROOT_CONTAINERS:="zroot/jails/containers"}        # containers will contain the jails.
...

sysrc -f /opt/info/environment ZROOT=${ZROOT}
sysrc -f /opt/info/environment ZROOT_MOUNT=${ZROOT_MOUNT}
sysrc -f /opt/info/environment ZROOT_MEDIA=${ZROOT_MEDIA}
sysrc -f /opt/info/environment ZROOT_TEMPLATES=${ZROOT_TEMPLATES}
sysrc -f /opt/info/environment ZROOT_CONTAINERS=${ZROOT_CONTAINERS}
...

jail_setup() {
        # Setup jail directories.
        zfs create -o mountpoint=${ZROOT_MOUNT} ${ZROOT}
        zfs create ${ZROOT_MEDIA}
        zfs create ${ZROOT_TEMPLATES}
        zfs create ${ZROOT_CONTAINERS}

        # Get a userland.
        if [ ! -f ${ZROOT_MOUNT}/media/14.2-RELEASE-base.txz ]; then
                echo "Fetching jail base to ${ZROOT_MOUNT}/media"
                fetch https://download.freebsd.org/ftp/releases/amd64/amd64/14.2-RELEASE/base.txz -o ${ZROOT_MOUNT}/media/14.2-RELEASE-base.txz
        fi

        # Set up a bridge for VNET.
        echo "Setting up ${CLONED_INTERFACE}"
        sysrc -f /etc/rc.conf cloned_interfaces="${CLONED_INTERFACE}"
        sysrc -f /etc/rc.conf "ifconfig_${DEFAULT_INTERFACE}=-rxcsum -txcsum -lro -vlanmtu -vlanhwcsum -vlanhwfilter -vlanhwtag up"
        sysrc -f /etc/rc.conf "ifconfig_${CLONED_INTERFACE}=addm ${DEFAULT_INTERFACE} up"
        ...
Have you heard of tools like Ansible (sysutils/ansible) or Puppet (sysutils/puppet8)? I think it's worthwhile to learn those, rather than hack up your own. A good challenge would be to try and translate the script you have into an Ansible playbook...

Psst! Yeah, Ansible is a RedHat thing (but so is Wayland! Shocker!), but FreeBSD doesn't give a rat's ass about that, and has both in Ports. 😈😏
 
I'm not sure if it was because I mentioned that I use /opt/info/environment
It is, at least for me. I'm not well understanding recent Linuxism, so I thought it is for setting environment variable that FreeBSD cannot.

And /opt/ does NOT exist on FreeBSD by default, and not a recommended way to do. (Linux apps that runs on Linuxulator would use /compat/linux/opt/, though.)
On FreeBSD, /usr/local/ is used instead of /opt/.
And for configurations, /usr/local/etc/ would be the good default. Some apps creates its own subdirectory in it.
For common data for all users that are NOT configurations (i.e., messages, language packs, and so on) would be preferred to be in per-app subdirectiries in /usr/local/share/.

parent-child-temp-file:
To see what I meant, script below would do.
sh:
#!/bin/sh

if [ "CHILD" = "${1}" ]
then
  echo -n "Current environment varible FOO is:"
  echo ${FOO}
  export FOO=BAR
  echo -n "Child process:"
  echo ${FOO}
else
  export FOO=BAZ
  echo -n "Parent process:"
  echo ${FOO}
  ${0} "CHILD"
  echo -n "Back to parent:"
  echo ${FOO}
fi

The result would be as below if the script is /tmp/test.sh and is executable.
Code:
% /tmp/test.sh
Parent process:BAZ
Current environment varible FOO is:BAZ
Child process:BAR
Back to parent:BAZ
%

Your parent-child-temp-file test seems to be testing global and local scope of shell variables that are NOT exported as environment variables.

For use-cases to place common file (I guess it defines shell variables in it) within all scripts you plan to provide would be something like /usr/local/share/JohnK/environment.
 
> Ansible
Sure. Things like that are on my 2do list but haven't gotten around to it (I have two small kids). ...I have a slew of setup scripts and they're all setup with these "things" like rcorder headers and whatnot. I know you're probably not interested but here is a brief tour anyways.

So (an example list):
doas_package.sh
doas_setup.sh
git_package.sh
jail_setup.sh
ntpd_setup.sh
rcconf_setup.sh
resolv_setup.sh

I can run the scripts individually (like in the need if I messed up a config and want to reset it back) or have something like a "runner script" for running a bunch of them (like for a "new setup" or "setup for using jails" or "whatever" need).

Example runner script.
Code:
# NOTE:
# A list of setup scripts to run, to perform a "setup", which filters
# through `rcorder` to pick the order in which they are run.

# run_setup_scripts_from_stdin --
#   This function will read lines from STDIN and execute it.
run_setup_scripts_from_stdin() {        #{{{
        while read -r fileline ; do
                case "$fileline" in
                *)
                 #
                 # DO NOT ACTUALLY DO ANYTHING BUT SAY HELLO
                 # 
                   echo "Hello from: ${fileline}"
                   ;;
                esac
        done
}
#}}}

/sbin/rcorder -s example_simple-setup.sh \
        /opt/conf/sys/setup_scripts/doas_setup.sh \
        /opt/conf/sys/setup_scripts/doas_package.sh \
        /opt/conf/sys/setup_scripts/jail_setup.sh \
        /opt/conf/sys/setup_scripts/resolv_setup.sh \
        /opt/conf/sys/setup_scripts/git_package.sh \
        | run_setup_scripts_from_stdin

> OPT / linux
My use of opt isn't a linux thing or need. The fact that it's not part of the base system files is the appeal (updates dont touch it). My "OPT directory" is mounted from my NAS (fileserver) so I have one set of config scripts I can use on multiple machines; for setting up a new server, I just change a few /opt/info/env file values and run the setup scripts.

Code:
HOSTNAME="server1"
INTERFACE="em0"
IP_ADDRESS="192.168.1.100"
GATEWAY="192.168.1.1"

It certainly could have been /usr/local/share/john/... I guess but, I just choose /opt (less typing maybe?). I think /opt was an old unix thing; I dont think it's specifically a linux thing; it's just a central place I can store stuff. Here is my opt directory.
Code:
/opt/               Contains optional scripts, configs, etc. for use in/with/of other tools to maintain system.

    scheduler/      Scheduler based
        cron/       Temporary holding directory for cron commands/files.
                    - cron files can be copied to and removed from
                      /etc/cron.d via scripts.

    info/           Place to store information type files (-e.g.
                    "db_password", "db_admin", "pkg_origins", etc.)

    conf/           A place to store configurations which can be
                    sourced in from system rc files or config files
                    for maintence scripts.

        backup/     Scripts preforming backup 'actions'.
        sys/        Scripts preforming 'actions' on system.

> parent-child
Yes, unfortunately the only way(s) I know to share a var from child->parent is to use a pipe (or file).

Code:
#!/bin/sh

# I made a temp file on your machine, 
# so I need to clean it up.
cleanup() {
  if [ -f "./test.temp" ]
  then
      rm ./test.temp
  fi
}

if [ "CHILD" = "${1}" ]
then
  echo -n "Current environment varible FOO is:"
  echo ${FOO}
  FOO=BAR       # modified syntax slightly to accommodate read/write to file.
  export FOO
  echo "Showing vars:"

  printf "  -> "; export -p | grep FOO
  echo "$FOO" > ./test.temp

  echo -n "Child process:"
  echo ${FOO}
else
  FOO=BAZ
  export FOO

  echo "Showing vars:"
  printf "  -> "; export -p | grep FOO
  echo "$FOO" > ./test.temp

  echo -n "Parent process:"
  echo ${FOO}
  ${0} "CHILD"
  echo -n "Back to parent:"

  # Unfortunately, the only method(s) to share from child->parent is to
  # use a temp file or pipe.
  read FOO < ./test.temp

  echo ${FOO}

  # cleanup (aka: remove) the temp file.
  cleanup
fi

However! That is very difficult to use.

Pipe.sh
Code:
#!/bin/sh

# Create a named pipe (FIFO)
pipe=$(mktemp -u)
mkfifo "$pipe"

# A function to act as child
child_process() {
    # Read from the pipe
    read FOO < "$pipe"
    echo "  Within child"
    printf -- "  The value of FOO is: %s\n" "$FOO"
    
    # Modify the variable and write back to the pipe
    echo "  Modifying the value to \"child\""
    FOO="child"
    echo "$FOO" > "$pipe"
}

# Start child process in background
child_process &

# Write the initial value to the pipe
FOO="parent"
echo "From parent"
printf -- "The inital value of FOO is: %s\n" "$FOO"
echo "$FOO" > "$pipe"

# Read the modified value from the pipe
read FOO < "$pipe"

# Now FOO in the parent process has the value set by the child
echo "Back to parent"
printf -- "The value of FOO is: %s\n" "$FOO"

# Clean up
rm "$pipe"

Okay, that's enough typing for now.
 
Yeah, looks like a great use case for Puppet.

Yeah, its your time, your metal, your efforts, your brains, your call.
 
Back
Top