Sprinting camera shake

I have a character and it can run while holding down the Shift Key. But it really feels very static. To make it more dynamic, I am trying to implement a camera shake, which works WHILE the Shift Key is held down.

I found some tutorials online but they work with coroutines and I am not great with them. I will insert the main code here.

This is the snippet that starts the coroutine.

        if (Input.GetKey(KeyCode.LeftShift) && !PauseMenu.isPaused)
        {
            actualMoveSpeed = 2 * moveSpeed;
            StartCoroutine(GameObject.Find("CameraHolder").GetComponent<CameraShake>().Shake());
        }

This is the actual Camera Shake class and the coroutine.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraShake : MonoBehaviour {

    public float magnitude = 1;

    public IEnumerator Shake()
    {
        Vector3 originalPos = transform.position;

        while(Input.GetKey(KeyCode.LeftShift))
        {
            float x = Random.Range(-1f, 1f) * magnitude;
            float y = Random.Range(-1f, 1f) * magnitude;

            transform.localPosition = new Vector3(x, y, originalPos.z);

            yield return null;
        }

        transform.localPosition = originalPos;
    }
}

But it doesn’t really work. When i press shift, the camera shakes like crazy. I think it’s because when i hold shift, I start a new coroutine every frame. The question is how can i make it work okay, and what improvements can be made?

Try to start coroutine with Input.GetKeyDown which returns true only once when you press the key during a frame instead of Input.GetKey which returns true every frame while you hold the key pressed.

if (Input.GetKeyDown(KeyCode.LeftShift) && !PauseMenu.isPaused)
     {
         actualMoveSpeed = 2 * moveSpeed;
         StartCoroutine(GameObject.Find("CameraHolder").GetComponent<CameraShake>().Shake());
     }

Also, you change position immediately every time so maybe it’s a reason why you get camera jumping like a mad. You should better use Lerp to change localPosition smoothly instead of just changing it immediately.
Here you might use Input.GetKey just like you did. Yes, the coroutine will be called every frame but with Lerp your camera should shake smoothly now.

 public IEnumerator Shake()
 {
     Vector3 originalPos = transform.position;

     while(Input.GetKey(KeyCode.LeftShift))
     {
         float x = Random.Range(-1f, 1f) * magnitude;
         float y = Random.Range(-1f, 1f) * magnitude;
         
         //'Lerp' linearly interpolates position from start position to end position
         // by specified float parameter (Vector3.Lerp (startPos, endPos, floatT))
         transform.localPosition = 
             Vector3.Lerp (
                 //1st param: start position
                 transform.localPosition,
                 //2nd param: end position we want transform to get in the end of lerp
                 new Vector3(x, y, originalPos.z),
                 //3rd param: float parameter
                 0,2f); //0f - position won't be changed,
                        //0.5f - position will be a half between start and end positions,
                        //1f - it will be changed to end position right now
                        //(as if there's no lerping used)
                        //try out different values here to get smooth speed you want

         yield return null;
     }

     transform.localPosition = originalPos;
 }