function defined in .zshrc not found when called from a script - function

I have defined some variables, aliases and functions in my .zshrc file:
export MY_VAR="example"
alias my_alias="echo an example"
function say_hello
{
echo "say hello"
}
I have verified that all three are defined and whatnot when called from the terminal. However, when I try to call the function say_hello from another script (which itself is called from the same terminal), the function does not appear to be defined. I see a 'command not found' error. The alias and variable MY_VAR appear to be defined just fine when referenced from this other script.
Any ideas on what might be going on? Thanks.

When zsh is called from a terminal it is invoked in interactive mode that causes zsh to source additional configuration files, including $ZDOTDIR/.zshrc ($HOME/.zshrc). By default (in non-interactive mode in non-login shell) it sources only /etc/zsh/zshenv* and $ZDOTDIR/.zshenv ($ZDOTDIR is most of time $HOME) files, see last but two section of man zsh named STARTUP/SHUTDOWN FILES. I have no idea why alias is defined (how exactly did you check?), but MY_VAR is defined in script because you exported it.
* /etc/zshenv according to doc, much likely they are Gentoo maintainers of zsh package who changed it to /etc/zsh/zshenv.
Note: it is bad idea to put such functions into .zshenv file as it creates implicit dependency. You should use script libraries instead: put it into
~/.zsh/say_hello.zsh
and do
source ${ZDOTDIR-$HOME}/.zsh/say_hello.zsh
in both your script and .zshrc.

Related

Setting envs or globals in bash script [duplicate]

How can I keep the environment variables, set from a shell script, after the script finishes running?
This is not possible by running the script. The script spawns it's own sub-shell which is lost when the script completes.
In order to preserve exports that you may have in your script, call it
either as
. myScript.sh
or
source myScript.sh
Notice the space between the . and myScript.sh; also note that "source is a synonym for . in Bash, but not in POSIX sh, so for maximum compatibility use the period."
run the script as follows:
source <script>
-OR-
. <script>
This will run the script in the current shell, and define variables in the current shell. The variables will then be retained in the current shell after the script is done.
Environment variables exist the the environment that is private to each process. The shell passes a COPY of exported variables to it's children as their environment, but there is no way for them to pass their environment back to the parent or any process other than their children.
You can print those variables and load them into the parent.
Or as has been already mentioned, you can run your script in the current shell with either "source script" or ". script" (and you might need ./script if . isn't in your PATH).
Some tools print their vars and the shell can load them using backticks like ssh-agent. That way whatever ssh-agent prints will be run as a command. If it prints something like "VAR1=VAL;VAR2=VAL2" that may do what you want.

Loading tcl extension from tclsh

I have a C extension to Tcl where command mytest is defined. The extension is compiled correctly (I am on Linux, extension is *.so). For example, I can start tclsh and use it like this:
$ tclsh
% load /path/extension.so
% mytest abc
...
But, if I create a file myscript.tcl with the following content:
load /path/extension.so
mytest abc
then I get error:
$ tclsh myscript.tcl
invalid command name "mytest"
while executing
"mytest abc"
(file "myscript.tcl" line 2)
I am using bash on Ubuntu 14.04. Tcl 8.6.
EDIT 1: My question/problem is that I want to use tclsh with a script as an argument - this script should properly load extensions in such a way that mytest and other implemented functions are working without error.
EDIT 2: Uhh, If I use command "source myscript.tcl" inside tcl shell the result is the same. If I use absolute path for myscript.tcl the error is still the same --- "load" executes without warning but I am not sure about it because I get invalid command name "mytest". Maybe the problem is with scope, but it is working correctly when tclsh is used interactively.
If you are using the full path of the extension library in both cases, that part should work identically. It probably is doing though; if it couldn't load it, it would generate an error (which might or might not be helpful, as some of the ways that things fail give very little information; Tcl reports what it has got, but that's sometimes not enough, as it is dependent on the OS to tell it some things). Instead, the problem is probably elsewhere.
The main difference between interactive use and scripted use is that in interactive use, the unknown command will expand unknown command names to Tcl commands that the thing you typed is an unambiguous prefix of. This is convenient, but when converting to a script, you should always use the full command name. OK, not the full full command name — you mostly don't want or need the :: namespace on the front — but without abbreviation, so don't use lappe for lappend. (In interactive use, Tcl will also exec things as external programs without requiring you to type the exec explicitly; again, that's turned off in scripts as it is rather fragile.)
Could it be that this is what is going on? You can check by setting the global variable tcl_interactive to 0 before typing in your code (I recommend using cut-n-paste for that typing, so that you know exactly what is going in). If that fails, it's the interactive-mode helpfulness that is tripping you up. Check what commands you might have as an expansion for a prefix with info commands (after the load, of course):
info commands mytest*
If that just reports mytest, my theory is wrong. (Well, if it does that and the length of that string is 6; there could theoretically be extra invisible characters have been put on the command name, which would be legal Tcl but very nasty and DON'T DO THAT!)

How to disable a modified tclsh interpreter interactive mode?

Run tclsh command without any tcl file, the interpreter will go into interactive mode.
Can I simply disable this feature by modifying the tclsh source code ?
I can't imagine why you would want to bother doing this, given that supplying any script file will turn off interactive mode. The script you supply will have full access to the additional arguments passed in (a list in the global argv variable) and the standard IO channels (stdin, stdout and stderr). It can exit when it is done. Literally anything you want can be done at that point; you've just got to write a script to do it.
If you're including Tcl in your own program, the behaviour of tclsh is implemented in the C function Tcl_Main. If you never call that — instead just using Tcl_FindExecutable, Tcl_CreateInterp and Tcl_Eval/Tcl_EvalFile — then you never get any of that interactive behaviour. While theoretically you could modify the Tcl source itself to do what you want — it's all open source — why would you bother when you could just not call that code in the first place?

Erlang: calling rr(?MODULE) from beam executable?

I'm not entirely sure how to define an Erlang function within an Erlang module. I'm getting the following error:
11> invoke_record:invoke().
** exception error: undefined function erlang:rr/1
From this simple code trying to invoke the rr(?MODULE). from within the beam executable in order to "initialize" records so that it doesn't need to be called from the shell every time.
-module(invoke_record).
-export([invoke/0]).
-record(process, {pid,
reference="",
lifetime=0
}).
invoke() ->
erlang:rr(?MODULE).
The command rr("file.hrl"). is meant to be be used only in shell for debugging purposes.
As other users highlighted in their answers, the correct way to import a record (or a function) contained in a .hrl file within your erlang code consists in using the command -include("file.hrl').
Once you have included the .hrl file in your code (and usually in a module based on OTP behaviours this is done after the -export(...) part) you can refer to the Erlang record (or function) without any problem.
rr is a shell command. You cannot use it it compiled code.
http://www.erlang.org/doc/man/shell.html
If your intent is to read many record definitions in the shell, in order to facilitate the debug, you can write a file containing all needed include statements and simply invoke rr once in the shell.
in rec.hrl:
-include("include/bank.hrl").
-include("include/reply.hrl").
and in the in the shell
1> rr("rec.hrl").
[account,reply]
2>
I didn't find any way to execute this automatically, when starting the VM.
When working on a project, you can gather all necessary includes and other command line arguments that you want to use for that particular project in a plain text file. After having made the plain text file, you can start your shell:
erl -args_file FileName
where FileName is the name of the plain text file. Note that all command line arguments accepted by erl are allowed. See also erl Flags in the ERTS Reference Manual

MATLAB error: Undefined function or method X for input arguments of type 'double' [duplicate]

This question already has answers here:
"Undefined function 'function_name' for input arguments of type 'double'."
(3 answers)
Closed 5 years ago.
I'm a new user of Matlab, can you please help:
I have the following code in an .M file:
function f = divrat(w, C)
S=sqrt(diag(diag(C)));
s=diag(S);
f=sqrt(w'*C*w)/(w'*s);
I have stored this file (divrat.M) in the normal Matlab path, and therefore I'm assuming that Matlab will read the function when it's starting and that this function therefore should be available to use.
However, when I type
>> divrat(w, C)
I get the following error
??? Undefined function or method 'divrat' for input arguments of type 'double'.
What is the error message telling me to do, I can't see any error in the code or the function call?
You get this error when the function isn't on the MATLAB path or in pwd.
First, make sure that you are able to find the function using:
>> which divrat
c:\work\divrat\divrat.m
If it returns:
>> which divrat
'divrat' not found.
It is not on the MATLAB path or in PWD.
Second, make sure that the directory that contains divrat is on the MATLAB path using the PATH command. It may be that a directory that you thought was on the path isn't actually on the path.
Finally, make sure you aren't using a "private" directory. If divrat is in a directory named private, it will be accessible by functions in the parent directory, but not from the MATLAB command line:
>> foo
ans =
1
>> divrat(1,1)
??? Undefined function or method 'divrat' for input arguments of type 'double'.
>> which -all divrat
c:\work\divrat\private\divrat.m % Private to divrat
As others have pointed out, this is very probably a problem with the path of the function file not being in Matlab's 'path'.
One easy way to verify this is to open your function in the Editor and press the F5 key. This would make the Editor try to run the file, and in case the file is not in path, it will prompt you with a message box. Choose Add to Path in that, and you must be fine to go.
One side note: at the end of the above process, Matlab command window will give an error saying arguments missing: obviously, we didn't provide any arguments when we tried to run from the editor. But from now on you can use the function from the command line giving the correct arguments.
The most common cause of this problem is that Matlab cannot find the file on it's search path. Basically, Matlab looks for files in:
The current directory (pwd);
Directly in a directory on the path (to see the path, type path at the command line)
In a directory named #(whatever the class of the first argument is) that is in any directory above.
As someone else suggested, you can use the command which, but that is often unhelpful in this case - it tells you Matlab can't find the file, which you knew already.
So the first thing to do is make sure the file is locatable on the path.
Next thing to do is make sure that the file that matlab is finding (use which) requires the same type as the first argument you are actually passing. I.el, If w is supposed to be different class, and there is a divrat function there, but w is actually empty, [], so matlab is looking for Double/divrat, when there is only a #(yourclass)/divrat. This is just speculation on my part, but this often bites me.
The function itself is valid matlab-code. The problem must be something else.
Try calling the function from within the directory it is located or add that directory to your searchpath using addpath('pathname').
The error code indicates the function definition cannot be found. Make sure you're calling the function from the same workspace as the divrat.m file is stored. And make sure divrat function is not a subfunction, it should be first function declaration in the file. You can also try to call the function from the same divrat.m file in order to see if the problem is with workspace selection or the function.
By the way, why didn't you simply say
s = sqrt(diag(C));
Wouldn't it be the same?
Also, name it divrat.m, not divrat.M. This shouldn't matter on most OSes, but who knows...
You can also test whether matlab can find a function by using the which command, i.e.
which divrat
I am pretty sure that the reason why this problem happened is because of the license of the toolbox (package) in which this function belongs in. Write which divrat and see what will be the result. If it returns path of the function and the comment Has no license available, then the problem is related to the license. That means, license of the package is not set correctly. Mostly it happens if the package (toolbox) of this function is added later, i.e., after installation of the original matlab. Please check and solve the license issue, then it will work fine.