There is ulimit -s 64M but that sets the stack size for all processes run after it
ulimit builtin in a shell operates on resource limits of the shell itself. It will affect each future child process because the limits get inherited when a child is created. (It may be little more complicated, we will get to this.)
I know it can also be done by get the PID and using a prlimit tool, but would rather have the stack size set immediately as part of running the process.
See man 1 prlimit. There are two ways the tool can operate:
It either takes a PID, this is what you described.
prlimit [options] [--resource[=limits]] [--pid PID]
Or it takes a command (+arguments) to execute, this is probably what you want.
prlimit [options] [--resource[=limits]] command [argument...]
In case prlimit is unavailable, use ulimit in a subshell:
(
ulimit … && # impose your setting(s)
binary–to-execute … # let the new process inherit them
)
later-command … # outside of the subshell, so unaffected*
Your shell may run the subshell as a separate child process (e.g. Bash does it this way), in this case the mechanism of inheriting resource limits will make this solution work straightforwardly. Or your shell may create a separate shell execution environment inside its own process (compare this answer). The latter way is where the ulimit builtin must not operate on resource limits of the entire shell process, so the shell shall do extra work to separate the environments and to set respective resource limits for binary-to-execute and later-command anyway.
If you are not sure your shell does it right, you can always explicitly run a totally separate shell process instead of the subshell. Example:
bash -c 'ulimit … && exec binary–to-execute …'
later-command …
Note in any case the binary-to-execute process may change limits for itself to some degree. Normally (in Linux: without CAP_SYS_RESOURCE capability) for each resource a process may set only its soft limit to a value in the range from 0 up to the hard limit, and (irreversibly) lower its hard limit. (See man 2 setrlimit.) If you want to firmly limit a process then you need to set the hard limit(s), so the process cannot increase its limits by itself.
* The statement that later-command is unaffected needs to be clarified. Resource limits are per process, so the limits themselves of later-command will not be affected by the ulimit we run in the subshell. But some counters are per user; for them if e.g. binary–to-execute forks to the background and consumes resources (increases the common counters) when our later-command runs, then in general it may affect how soon later-command reaches its limits.
As an example take ulimit -u, it sets the maximum number of user processes. I'm sure the counter is per user. A process with high maximum may spawn many children, even to the point where another process with lower maximum cannot (because the common counter has already exceeded the limit set for this process) while the process with high maximum still can (because the common counter has not yet exceeded the limit set for this process).
I guess the stack size that matters for ulimit -s is counted per process, but I'm not a programmer and I don't really know.