help with setting up aliases/functions
#1
help with setting up aliases/functions
ok so I've been trying to craft myself some tools/aliases for my dev work. I first started with making aliases, but then they got too complex and so I decided to turn them into functions which get loaded up via .profile.  So Everything works fine, If I do a "source .profile" I get no errors, but whenever I log into the account I get a bunch of errors - anyone have any idea?

Here is an example (I'm using bash btw because it supports functions)

Code:
-bash-4.2$ cat ~/.profile
##### Setup Functions #####
helloworld () {
  echo "hello World!"
}
export -f helloworld
-bash-4.2$ 
-bash-4.2$ helloworld
hello World!
-bash-4.2$ source ~/.profile
-bash-4.2$ 

so the function works and was exported to my shell - but when I login or open a new shell I always get the below - I'm trying to figure out how to (cleanly) fix this

Code:
-bash: helloworld: line 1: syntax error: unexpected end of file
-bash: error importing function definition for `helloworld'




for anyone curious, here are my old aliases using csh.  most of them didn't work because of limitations of aliases and using command-line arguments:
Code:
alias hreplace="find . -type f -name '*.h' -exec gsed -i 's/$1/$2/g' {} \;"
alias creplace="find . -type f -name '*.c' -exec gsed -i 's/$1/$2/g' {} \;"
alias mreplace="find . -type f -name 'Makefile' -exec gsed -i 's/$1/$2/g' {} \;"
alias searchfor="find . | xargs file | grep 'text' | cut -f1 -d: | xargs grep $1"
alias dos2unix="gsed -i 's/<cr>$//g' $1"


here are my new functions using bash:
Code:
##### Setup Functions #####

#search and replace string in *.h files in current dir tree
hreplace () {
echo ""
echo "Replacing \"$1\" with \"$2\" in all *.h files in \""`pwd`"/*\""
echo ""
find . -type f -name '*.h' -exec gsed -i "s/$1/$2/g" {} \;
}
export -f hreplace

#search and replace string in *.c files in current dir tree
creplace () {
echo ""
echo "Replacing \"$1\" with \"$2\" in all *.c files in \""`pwd`"/*\""
echo ""
find . -type f -name '*.c' -exec gsed -i "s/$1/$2/g" {} \;
}
export -f creplace

#search and replace string in "Makefile" files in current dir tree
mreplace () {
echo ""
echo "Replacing \"$1\" with \"$2\" in all \'Makefile\" files in \""`pwd`"/*\""
echo ""
find . -type f -name 'Makefile' -exec gsed -i "s/$1/$2/g" {} \;
}
export -f mreplace

#search for a text string in all text files in current dir tree
searchall () {
printf '\n'
find . | xargs file | grep 'text' | cut -f1 -d: |  xargs grep $1
printf '\n';
}
export -f searchall

#search for a text string in all *.c files in current dir tree
csearch () {
printf '\n'
find . | xargs file | grep 'text' | cut -f1 -d: | grep .c$ | xargs grep $1
printf '\n';
}
export -f csearch

#search for a text string in all *.h files in current dir tree
hsearch () {
printf '\n'
find . | xargs file | grep 'text' | cut -f1 -d: | grep .h$ | xargs grep $1
printf '\n';
}
export -f hsearch

#search for a text string in all "Makefile" files in current dir tree
msearch () {
printf '\n'
find . | xargs file | grep 'text' | cut -f1 -d: | grep Makefile$ | xargs grep $1
printf '\n';
}
export -f msearch


here is an example of these functions/aliases in action:
Code:
-bash-4.2$ searchall __inline__

./fm.c://#define INLINE __inline__
./driver.h://#define __inline__ /**/
./m68kconf.h://#define INLINE static __inline__
./musa/m68kconf.h://#define INLINE static __inline__

-bash-4.2$ csearch __inline__

./fm.c://#define INLINE __inline__

-bash-4.2$ hsearch __inline__

./driver.h://#define __inline__ /**/
./m68kconf.h://#define INLINE static __inline__
./musa/m68kconf.h://#define INLINE static __inline__

-bash-4.2$ creplace __inline__ __inline  

Replacing "__inline__" with "__inline" in all *.c files in "/usr/people/develop/dev/dgen/first_try/dgen-sdl-1.23/*"

-bash-4.2$ csearch __inline

./fm.c://#define INLINE __inline

-bash-4.2$ hsearch __inline

./driver.h://#define __inline__ /**/
./m68kconf.h://#define INLINE static __inline__
./musa/m68kconf.h://#define INLINE static __inline__

-bash-4.2$ hreplace __inline__ youAintGonnaFoolMeAgainSucka

Replacing "__inline__" with "youAintGonnaFoolMeAgainSucka" in all *.h files in "/usr/people/develop/dev/dgen/first_try/dgen-sdl-1.23/*"

-bash-4.2$ hsearch __inline


-bash-4.2$ hsearch Foo

./driver.h://#define youAintGonnaFoolMeAgainSucka /**/
./m68kconf.h://#define INLINE static youAintGonnaFoolMeAgainSucka
./musa/m68kconf.h://#define INLINE static youAintGonnaFoolMeAgainSucka

-bash-4.2$ 
gijoe77
Tezro

Posts: 469
Threads: 28
Joined: Jun 2018
Find Reply
09-08-2018, 05:11 AM
#2
RE: help with setting up aliases/functions
Is this happening with only one function definition in .profile ?

I would check several things as well:
- Removing 1st line of comment
- indent expression between brackets { and }

Bash related functions and variables should be placed in ~/.bashrc and let ~/.profile source it, at least that is how i am used to it in Linux world.
dexter1
Global Moderator
******

Posts: 166
Threads: 9
Joined: May 2018
Find Reply
09-08-2018, 02:55 PM
#3
RE: help with setting up aliases/functions
I get the error messages for all functions in .profile, even if I move them and source ~/.bashrc or ~/.bash_profile, it all seems to point to an issue at login.  Once I'm logged in tho, I can source ~/.profile or ~/.bashrc or ~/.bash_profile or do anything and not get the shell to throw out any complaints.  It's super strange to me.

I tried 


Code:
helloworld () {
  echo "hello World!"
}

helloworld() {
  echo "hello World!"
}

helloworld()
{
  echo "hello World!"
}

...etc


I'm working around it by putting all the functions into a separate script and making an alias to run that script, but I am puzzled why its not working - It seems to me it should work fine, but I just wanted to get some other eyes on it.

 Here is the full .profile with the functions still in it


Code:
#
# This is the default standard .profile provided to sh users.
# They are expected to edit it to meet their own needs.
#
# The commands in this file are executed when an sh user first
# logs in.
#
# $Revision: 1.1 $
#

if [ -z "$ENVONLY" ]
then
# Set the interrupt character to Ctrl-c and do clean backspacing.
if [ -t 0 ]
then
stty intr '^C' echoe
fi

# Set the TERM environment variable
eval `tset -s -Q`
fi

# Set the default X server.
if [ ${DISPLAY:-setdisplay} = setdisplay ]
then
   if [ ${REMOTEHOST:-islocal} != islocal ]
   then
       DISPLAY=${REMOTEHOST}:0
   else
       DISPLAY=:0
   fi
   export DISPLAY
fi



##### Setup PATHS #####

#setup PATH
export PATH=${PATH}:/usr/local/bin:/usr/nekoware/bin

#setup MANPATH for man pages
export MANPATH=/usr/local/man:/usr/local/share/man:/usr/nekoware/share/man:/usr/nekoware/man:/usr/share/catman:/usr/share/man:/usr/man

#setup lib search path
export LD_LIBRARY_PATH=/usr/local/lib:/usr/nekoware/lib


##### Setup Functions #####

#search and replace string in *.h files in current dir tree
hreplace () {
echo ""
echo "Replacing \"$1\" with \"$2\" in all *.h files in \""`pwd`"/*\""
echo ""
find . -type f -name '*.h' -exec gsed -i "s/$1/$2/g" {} \;
}
export -f hreplace

#search and replace string in *.c files in current dir tree
creplace () {
echo ""
echo "Replacing \"$1\" with \"$2\" in all *.c files in \""`pwd`"/*\""
echo ""
find . -type f -name '*.c' -exec gsed -i "s/$1/$2/g" {} \;
}
export -f creplace

#search and replace string in "Makefile" files in current dir tree
mreplace () {
echo ""
echo "Replacing \"$1\" with \"$2\" in all \'Makefile\" files in \""`pwd`"/*\""
echo ""
find . -type f -name 'Makefile' -exec gsed -i "s/$1/$2/g" {} \;
}
export -f mreplace

#search for a text string in all text files in current dir tree
searchall () {
printf '\n'
find . | xargs file | grep 'text' | cut -f1 -d: |  xargs grep $1
printf '\n';
}
export -f searchall

#search for a text string in all *.c files in current dir tree
csearch () {
printf '\n'
find . | xargs file | grep 'text' | cut -f1 -d: | grep .c$ | xargs grep $1
printf '\n';
}
export -f csearch

#search for a text string in all *.h files in current dir tree
hsearch () {
printf '\n'
find . | xargs file | grep 'text' | cut -f1 -d: | grep .h$ | xargs grep $1
printf '\n';
}
export -f hsearch

#search for a text string in all "Makefile" files in current dir tree
msearch () {
printf '\n'
find . | xargs file | grep 'text' | cut -f1 -d: | grep Makefile$ | xargs grep $1
printf '\n';
}
export -f msearch


##### Setup Aliases #####

#remove DOS/Windows ^M carriage-return
alias dos2unix="gsed -i 's/
$//g' $1"
gijoe77
Tezro

Posts: 469
Threads: 28
Joined: Jun 2018
Find Reply
09-09-2018, 08:42 AM
#4
RE: help with setting up aliases/functions
bash(1) mentions in INVOCATION that when invoked as login shell it first reads /etc/profile and then either one of ~/.bash_profile, ~/.bash_login or ~/.profile. So if all these three files exist, bash will only read in the first one. Did you anticipate this behaviour?

Well, the above doesn't explain that:
(09-08-2018, 05:11 AM)gijoe77 Wrote:  
Code:
-bash: helloworld: line 1: syntax error: unexpected end of file
-bash: error importing function definition for `helloworld'
It sounds a little like a closing keyword or character is missing somewhere, but I don't see something like that in your .profile.

Just to be sure, does your .profile use Unix line endings everywhere?

Indigo Indy Indigo2 IMPACT O2 Octane Octane2 Origin 200 = Origin 200 - Origin 200 = Origin 200

johnnym
O2

Posts: 39
Threads: 2
Joined: Jun 2018
Find Reply
09-12-2018, 08:13 AM
#5
RE: help with setting up aliases/functions
(09-12-2018, 08:13 AM)johnnym Wrote:  bash(1) mentions in INVOCATION that when invoked as login shell it first reads /etc/profile and then either one of ~/.bash_profile, ~/.bash_login or ~/.profile. So if all these three files exist, bash will only read in the first one. Did you anticipate this behaviour?
yes.  I kept everything in just .profile (for simplicity sake).  I tried .bash_profile and .bashrc, but same results.

(09-12-2018, 08:13 AM)johnnym Wrote:  Just to be sure, does your .profile use Unix line endings everywhere?


I'm not sure what you mean?  Do you mean unix carriage returns?  If so then yes, I wrote everything on-the-fly in the shell.

I am under the impression if this was a syntax problem or coding error I would get an error when I source the file, but it's only on login, so there seems to be a step happening at login that is throwing everything off and I just can't seem to figure it out.

the way I'm currently working around this is putting my functions into a separate file (i.e ~/scripts/functions) and making an alias to source that file when I'm looking to load them, but I would rather just have everything loaded and done at login, but oh well, as long as it still works ^_^
gijoe77
Tezro

Posts: 469
Threads: 28
Joined: Jun 2018
Find Reply
09-12-2018, 11:01 AM
#6
RE: help with setting up aliases/functions
(09-12-2018, 11:01 AM)gijoe77 Wrote:  
(09-12-2018, 08:13 AM)johnnym Wrote:  Just to be sure, does your .profile use Unix line endings everywhere?
I'm not sure what you mean?  Do you mean unix carriage returns?  If so then yes, I wrote everything on-the-fly in the shell.
If you typed this in in your shell I assume the result is with correct line endings. BTW, only line feed is used as line ending on Unix-like operating systems - and as I just found out this was also already used in Multics - carriage return and line feed is used for example in Windows but also in other operating systems.

UPDATE: Rereading your posts, you seem to use a shell function that translates line endings between DOS and Unix, hence I assume you already know the difference. But then I'm not sure why you wrote "unix carriage returns" - maybe a typo and you meant Windows instead.  Huh

(09-12-2018, 11:01 AM)gijoe77 Wrote:  I am under the impression if this was a syntax problem or coding error I would get an error when I source the file, but it's only on login, so there seems to be a step happening at login that is throwing everything off and I just can't seem to figure it out.
It could be that the other files (e.g. /etc/profile, which might again include additional files) break things when bash is used as login shell. You could try to verify these files or even strip them down to the absolute minimum and try again. On the other hand, if the problems started with the modification of your ~/.profile, the other files could be considered valid. Maybe you check with a new user and empty home directory, start there from scratch and relogin after each change.

All this assumes that the used bash binary works correctly. Say, have you tried with an older version, already?

(09-12-2018, 11:01 AM)gijoe77 Wrote:  the way I'm currently working around this is putting my functions into a separate file (i.e ~/scripts/functions) and making an alias to source that file when I'm looking to load them
A shell alias? Interesting, how did you define that and how to you use it to source that file?

Indigo Indy Indigo2 IMPACT O2 Octane Octane2 Origin 200 = Origin 200 - Origin 200 = Origin 200

johnnym
O2

Posts: 39
Threads: 2
Joined: Jun 2018
Find Reply
09-12-2018, 05:56 PM
#7
RE: help with setting up aliases/functions
carriage returns/linefeeds - that silly ^M windows likes to add at the end of each line Smile

I did this on a new account, and I only modified the .profile file, when I remove the functions from .profile I get no errors.  I might try a new bash, I'm using the updated nekoware version

The alias looks like this


Code:
alias loadfunctions="source ~/scripts/functions"
gijoe77
Tezro

Posts: 469
Threads: 28
Joined: Jun 2018
Find Reply
09-13-2018, 10:21 PM
#8
RE: help with setting up aliases/functions
Hi gijoe77!!!

I believe this is due to porting issues and hence should be fixed in bash source code/Makefiles/configure. Have you tried using debugging?

set -x
##### Setup Functions #####
helloworld () {
  echo "hello World!"
}
export -f helloworld
set +x


If it still throws the same error at least you know exactly what line/command is the offending one.


Next step is deep diving into source code and doing the hard work...

Good luck!
TruHobbyist
O2

Posts: 43
Threads: 6
Joined: May 2018
Find Reply
09-14-2018, 11:56 AM
#9
RE: help with setting up aliases/functions
Hi Tru!

I didn't even know about this debugging feature!  pretty neat!  Here is what I got:


Code:
-bash: helloworld: line 1: syntax error: unexpected end of file
-bash: error importing function definition for `helloworld'
+ export -f helloworld
+ set +x
-bash-4.2$ 

so it seems it doesn't like the export line when logging in, but once logged in it works fine.

Unfortunately I'm just not at the point where I can jump into this sort of code and find the issue yet,  I'm literately trying to figure out how to gdb/dbx helloworld!  Baby steps..
gijoe77
Tezro

Posts: 469
Threads: 28
Joined: Jun 2018
Find Reply
09-15-2018, 02:39 AM
#10
RE: help with setting up aliases/functions
so here is what I ended up doing, if anyone feels like playing with it.  I would love to see what sort of dev environment anyone else has set up..


Code:
// .profile
#
# This is the default standard .profile provided to sh users.
# They are expected to edit it to meet their own needs.
#
# The commands in this file are executed when an sh user first
# logs in.
#
# $Revision: 1.1 $
#

if [ -z "$ENVONLY" ]
then
# Set the interrupt character to Ctrl-c and do clean backspacing.
if [ -t 0 ]
then
stty intr '^C' echoe
fi

# Set the TERM environment variable
eval `tset -s -Q`
fi

# Set the default X server.
if [ ${DISPLAY:-setdisplay} = setdisplay ]
then
   if [ ${REMOTEHOST:-islocal} != islocal ]
   then
       DISPLAY=${REMOTEHOST}:0
   else
       DISPLAY=:0
   fi
   export DISPLAY
fi



##### Setup PATHS #####

#setup PATH
export PATH=${PATH}:/usr/local/bin:/usr/nekoware/bin

#setup MANPATH for man pages
export MANPATH=/usr/local/man:/usr/local/share/man:/usr/nekoware/share/man:/usr/nekoware/man:/usr/share/catman:/usr/share/man:/usr/man

#setup lib search path
export LD_LIBRARY_PATH=/usr/local/lib:/usr/nekoware/lib


##### Setup Functions #####
# moved to scripts/text_functions.sh due to error messages at login

##### Setup Aliases #####

#remove DOS/Windows ^M carriage-return
alias tools="source ~/scripts/text_functions.sh"
alias toolshelp="cat ~/scripts/text_functions.help"
alias dos2unix="gsed -i 's/
$//g' $1"


Code:
// ~/scripts/text_functions.help

  ## List of available "tools" commands ##

  # SEARCH #

   searchall <string>
     - search for a <string> in all text files within .

   csearch <string>
     - search for a text string in all *.c files within .

   hsearch <string>
     - search for a text string in all *.h files within .

   msearch <string>
     - search for a text string in all Makefile* files within .

  # REPLACE #

   creplace <A> <B>
     - replace "A" with "B" strings in all *.c files within .

   hreplace <A> <B>
     - replace "A" with "B" strings in all *.h files within .

   mreplace <A> <B>
     - replace "A" with "B" strings in all Makefile* files within .



Code:
// ~/scripts/text_functions.sh
#!/usr/nekoware/bin/bash
#search and replace string in *.h files in current dir tree
hreplace () {
echo ""
echo "Replacing \"$1\" with \"$2\" in all *.h files in \""`pwd`"/*\""
echo ""
find . -type f -name '*.h' -exec gsed -i "s/$1/$2/g" {} \;
}
export -f hreplace

#search and replace string in *.c files in current dir tree
creplace () {
echo ""
echo "Replacing \"$1\" with \"$2\" in all *.c files in \""`pwd`"/*\""
echo ""
find . -type f -name '*.c' -exec gsed -i "s/$1/$2/g" {} \;
}
export -f creplace

#search and replace string in "Makefile" files in current dir tree
mreplace () {
echo ""
echo "Replacing \"$1\" with \"$2\" in all \'Makefile\" files in \""`pwd`"/*\""
echo ""
find . -type f -name 'Makefile' -exec gsed -i "s/$1/$2/g" {} \;
}
export -f mreplace

#search for a text string in all text files in current dir tree
#edit: remove any "c program text with garbage" from output 
searchall () {
printf '\n'
find . | xargs file | grep 'text' | grep -v "c program text with garbage" | cut -f1 -d: |  xargs grep $1
printf '\n';
}
export -f searchall

#search for a text string in all *.c files in current dir tree
csearch () {
printf '\n'
find . | xargs file | grep 'text' | cut -f1 -d: | grep .c$ | xargs grep $1
printf '\n';
}
export -f csearch

#search for a text string in all *.h files in current dir tree
hsearch () {
printf '\n'
find . | xargs file | grep 'text' | cut -f1 -d: | grep .h$ | xargs grep $1
printf '\n';
}
export -f hsearch

#search for a text string in all "Makefile" files in current dir tree
msearch () {
printf '\n'
find . | xargs file | grep 'text' | cut -f1 -d: | grep Makefile$ | xargs grep $1
printf '\n';
}
export -f msearch
gijoe77
Tezro

Posts: 469
Threads: 28
Joined: Jun 2018
Find Reply
09-15-2018, 03:53 AM


Forum Jump:


Users browsing this thread: 1 Guest(s)