babelfish icon indicating copy to clipboard operation
babelfish copied to clipboard

Multiple erros when sourcing translated /etc/profile on Arch

Open ohmree opened this issue 3 years ago • 2 comments

$ babelfish < /etc/profile | source
read: Unknown option “-r”

Standard input (line 1): 
; while read -r install_path
        ^

(Type 'help read' for related documentation)
- (line 12): $- is not a valid variable in fish.
  test "$-" = '*''i''*' || set runcnf '0'
         ^
from sourcing file -
        called on line 23 of file -
from sourcing file -
source: Error while reading file “-”
set: Unknown option “-f”

- (line 28): 
set -e -f; set -e append_path
^
from sourcing file -

(Type 'help set' for related documentation)

Where the original /etc/profile looks like this:

# /etc/profile

# Set our umask
umask 022

# Append "$1" to $PATH when not already in.
# This function API is accessible to scripts in /etc/profile.d
append_path () {
    case ":$PATH:" in
        *:"$1":*)
            ;;
        *)
            PATH="${PATH:+$PATH:}$1"
    esac
}

# Append our default paths
append_path '/usr/local/sbin'
append_path '/usr/local/bin'
append_path '/usr/bin'

# Force PATH to be environment
export PATH

# Load profiles from /etc/profile.d
if test -d /etc/profile.d/; then
	for profile in /etc/profile.d/*.sh; do
		test -r "$profile" && . "$profile"
	done
	unset profile
fi

# Unload our profile API functions
unset -f append_path

# Source global bash config, when interactive but not posix or sh mode
if test "$BASH" &&\
   test "$PS1" &&\
   test -z "$POSIXLY_CORRECT" &&\
   test "${0#-}" != sh &&\
   test -r /etc/bash.bashrc
then
	. /etc/bash.bashrc
fi

# Termcap is outdated, old, and crusty, kill it.
unset TERMCAP

# Man is much better than us at figuring this out
unset MANPATH

And the fish translation:

# /etc/profile
# Set our umask
umask 022
# Append "$1" to $PATH when not already in.
# This function API is accessible to scripts in /etc/profile.d
function append_path
  switch ':'"$PATH"':'
  case '*:'$argv[1]':*'
    
  case '*'
    set PATH (test -n "$PATH" && echo "$PATH"':' || echo)$argv[1]
  end
end
# Append our default paths
append_path '/usr/local/sbin'
append_path '/usr/local/bin'
append_path '/usr/bin'
# Force PATH to be environment
set -gx PATH $PATH
# Load profiles from /etc/profile.d
if test -d /etc/profile.d/
  for profile in /etc/profile.d/*.sh
    test -r "$profile" && babelfish < "$profile" | source
  end
  set -e profile
end
# Unload our profile API functions
set -e -f; set -e append_path
# Source global bash config, when interactive but not posix or sh mode
if test "$BASH" && test "$PS1" && test -z "$POSIXLY_CORRECT" && test $argv[0] != sh && test -r /etc/bash.bashrc
  babelfish < /etc/bash.bashrc | source
end
# Termcap is outdated, old, and crusty, kill it.
set -e TERMCAP
# Man is much better than us at figuring this out
set -e MANPATH

I think one problem is that unset -f append_path translates to set -e -f; set -e append_path, at least that's what I understand from one of the errors.
This should probably get translated to a functions -e call instead.

Now for the files under /etc/profile.d/:

The first error about the unknown option for read seems to come from /etc/profile.d/flatpak.sh (found it with rg 'while read' /etc/profile.d).
I don't know if there's a fish equivalent to read -r or if it's needed here. Original:

if command -v flatpak > /dev/null; then
    # set XDG_DATA_DIRS to include Flatpak installations

    new_dirs=$(
        (
            unset G_MESSAGES_DEBUG
            echo "${XDG_DATA_HOME:-"$HOME/.local/share"}/flatpak"
            GIO_USE_VFS=local flatpak --installations
        ) | (
            new_dirs=
            while read -r install_path
            do
                share_path=$install_path/exports/share
                case ":$XDG_DATA_DIRS:" in
                    (*":$share_path:"*) :;;
                    (*":$share_path/:"*) :;;
                    (*) new_dirs=${new_dirs:+${new_dirs}:}$share_path;;
                esac
            done
            echo "$new_dirs"
        )
    )

    export XDG_DATA_DIRS
    XDG_DATA_DIRS="${new_dirs:+${new_dirs}:}${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
fi

And translation:

if command -v flatpak >/dev/null
  # set XDG_DATA_DIRS to include Flatpak installations
  set new_dirs (fish -c 'set -e G_MESSAGES_DEBUG; echo (test -n "$XDG_DATA_HOME" && echo "$XDG_DATA_HOME" || echo "$HOME"\'/.local/share\')\'/flatpak\'; GIO_USE_VFS=\'local\' flatpak --installations' | fish -c '; while read -r install_path
    set share_path "$install_path"\'/exports/share\'
    switch \':\'"$XDG_DATA_DIRS"\':\'
    case \'*\'\':\'"$share_path"\':\'\'*\'
      :
    case \'*\'\':\'"$share_path"\'/:\'\'*\'
      :
    case \'*\'
      set new_dirs (test -n "$new_dirs" && echo "$new_dirs"\':\' || echo)"$share_path"
    end
  end; echo "$new_dirs"' | string collect; or echo)
  set -gx XDG_DATA_DIRS $XDG_DATA_DIRS
  set XDG_DATA_DIRS (test -n "$new_dirs" && echo "$new_dirs"':' || echo)(test -n "$XDG_DATA_DIRS" && echo "$XDG_DATA_DIRS" || echo '/usr/local/share:/usr/share')
end

The last error source that I managed to track down is in /etc/profile.d/PackageKit.sh, notice how the $- variable is getting translated verbatim.
The ideal solution would be to translate the whole check to a status is-* invocation but I don't know how much effort this requires and if it requires any weird special-casing. Original:

# Copyright (C) 2008 Richard Hughes <[email protected]>
#
# Licensed under the GNU General Public License Version 2
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

command_not_found_handle () {
	local runcnf=1
	local retval=127

	# only search for the command if we're interactive
	[[ $- == *"i"* ]] || runcnf=0

	# don't run if DBus isn't running
	[[ ! -S /run/dbus/system_bus_socket ]] && runcnf=0

	# don't run if packagekitd doesn't exist in the _system_ root
	[[ ! -x '/usr/lib/packagekitd' ]] && runcnf=0

	# don't run if bash command completion is being run
	[[ -n ${COMP_CWORD-} ]] && runcnf=0
	
	# don't run if we've been uninstalled since the shell was launched
	[[ ! -x '/usr/lib/pk-command-not-found' ]] && runcnf=0

	# run the command, or just print a warning
	if [ $runcnf -eq 1 ]; then
		'/usr/lib/pk-command-not-found' "$@"
		retval=$?
	elif [[ -n "${BASH_VERSION-}" ]]; then
		printf >&2 'bash: %scommand not found\n' "${1:+$1: }"
	fi

	# return success or failure
	return $retval
}

if [[ -n "${ZSH_VERSION-}" ]]; then
	command_not_found_handler () {
		command_not_found_handle "$@"
	}
fi

Translation:

# Copyright (C) 2008 Richard Hughes <[email protected]>
#
# Licensed under the GNU General Public License Version 2
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
function command_not_found_handle
  set -l runcnf '1'
  set -l retval '127'
  # only search for the command if we're interactive
  test "$-" = '*''i''*' || set runcnf '0'
  # don't run if DBus isn't running
  test ! -S '/run/dbus/system_bus_socket' && set runcnf '0'
  # don't run if packagekitd doesn't exist in the _system_ root
  test ! -x '/usr/lib/packagekitd' && set runcnf '0'
  # don't run if bash command completion is being run
  test -n (set -q COMP_CWORD && echo "$COMP_CWORD" || echo '') && set runcnf '0'
  # don't run if we've been uninstalled since the shell was launched
  test ! -x '/usr/lib/pk-command-not-found' && set runcnf '0'
  # run the command, or just print a warning
  if [ $runcnf -eq 1 ]
    '/usr/lib/pk-command-not-found' "$argv"
    set retval "$status"
  else if test -n (set -q BASH_VERSION && echo "$BASH_VERSION" || echo '')
    printf 'bash: %scommand not found\\n' $argv[1] >&2
  end
  # return success or failure
  return $retval
end
if test -n (set -q ZSH_VERSION && echo "$ZSH_VERSION" || echo '')
  function command_not_found_handler
    command_not_found_handle "$argv"
  end
end

Sorry for the wall of text issue, I don't know enough about the causes of these errors to open separate issues for them but I guess I could try if I'd be pointed in the right direction. Anyways, I guess I'll be switching back to replay for now.

ohmree avatar Jun 23 '21 20:06 ohmree

Thanks for the detailed issue—these are quite tricky bash idioms so they might not translate very well

bouk avatar Jul 04 '21 09:07 bouk

Thanks for the detailed issue—these are quite tricky bash idioms so they might not translate very well

Fair enough, I can definitely see how some of these can be tricky to translate.

I hope this issue will at least help fellow Arch users who also run into the same issues.

ohmree avatar Jul 06 '21 17:07 ohmree