Quite a few options here, so I'll just add, it depends.
If you have a standard Linux shell runner, without any extra configuration and installed the way GitLab suggest, you'll have a path something along the lines of:
/home/gitlab-runner/builds/$RUNNER_TOKEN_KEY/$CONCURRENT_ID/$NAMESPACE/$PROJECT_NAME
This directory can be changed with builds_dir option in the runner config.toml.
Another point to add, is that in your script, you can also echo out the location files, and also to specify where to save a file on the runner, eg:
script:
- echo ${CI_PROJECT_DIR}
- date > ${CI_PROJECT_DIR}/hello.txt
See GitLab's pre-defined environment variables for more options.
By default, all jobs are within this ${CI_PROJECT_DIR}, so when you start a script section, you can usually safely assume that you are in this directory without having to do a cd ${CI_PROJECT_DIR} for example.
You also most likely want all the job to be done within this ${CI_PROJECT_DIR} because the GitLab runner also handles the cleanup when a new job starts. By default, the runner does a git clean -ffdx after checking out the repository, and so in this example, would remove the hello.txt file before continuing with the job. See git clean flags for more information.
Just be wary of handling concurrency on shell runners if they share the same build directory.
HTH!